51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

uniapp-x与springboot跑通websocket示例

万人都要将火熄灭,我一人独将此火高高举起。------海子

uniapp-x

utils/device.ts

|---------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | hljs typescript /** * 获取设备唯一标识符 * @returns {string} 唯一设备标识符 */ export function getUniqueDeviceId(): string { let deviceId: string | null = uni.getStorageSync('deviceId'); // 从本地缓存获取 if (!deviceId) { // 如果不存在,生成新的 UUID deviceId = generateUUID(); uni.setStorageSync('deviceId', deviceId); // 存储到本地 } console.log('设备唯一标识: ', deviceId); return deviceId; } /** * 生成随机 UUID * @returns {string} UUID 字符串 */ export function generateUUID(): string { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace( /[xy]/g, (substring: string, ...args: any[]): string => { const random: number = (Math.random() * 16) | 0; const value: number = substring === 'x' ? random : (random & 0x3) | 0x8; return value.toString(16); } ); } |

pages/index/index.uvue

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | hljs uvue <template> <page-head title="websocket通讯示例"></page-head> <view class="uni-padding-wrap"> <view class="uni-btn-v"> <text class="websocket-msg">{{ showMsg }}</text> <button class="uni-btn-v" type="primary" @click="connect"> 连接websocket服务 </button> <button class="uni-btn-v" v-show="connected" type="primary" @click="send"> 发送一条消息 </button> <button class="uni-btn-v" type="primary" @click="close"> 断开websocket服务 </button> <text class="websocket-tips">发送消息后会收到一条服务器返回的消息(与发送的消息内容一致)</text> <button class="uni-btn-v" type="primary" @click="goSocketTask"> 跳转 socketTask 示例 </button> </view> </view> </template> <script> import { getUniqueDeviceId } from '@/utils/device'; export default { data() { return { connected: false, connecting: false, msg: '', roomId: '', platform: '', deviceId: '' } }, computed: { showMsg() : string { if (this.connected) { if (this.msg.length > 0) { return '收到消息:' + this.msg } else { return '等待接收消息' } } else { return '尚未连接' } }, }, onLoad() { this.platform = uni.getSystemInfoSync().platform }, onUnload() { uni.closeSocket({ code: 1000, reason: 'close reason from client', success: (res : any) => { console.log('uni.closeSocket success', res) }, fail: (err : any) => { console.log('uni.closeSocket fail', err) }, } as CloseSocketOptions) uni.hideLoading() }, methods: { connect() { if (this.connected || this.connecting) { uni.showModal({ content: '正在连接或者已经连接,请勿重复连接', showCancel: false, }) return } this.connecting = true uni.showLoading({ title: '连接中...', }) this.deviceId = getUniqueDeviceId(); const url = `ws://192.168.1.27:8080/ws?deviceId=${encodeURIComponent(this.deviceId)}`; setTimeout(() => { if (this.connected) { return } this.connecting = false uni.hideLoading(); uni.showToast({ icon: 'none', title: '连接超时', }) }, 10000) uni.connectSocket({ url, header: null, protocols: null, success: (res : any) => { // 这里是接口调用成功的回调,不是连接成功的回调,请注意 console.log('uni.connectSocket success', { url, res }) }, fail: (err : any) => { // 这里是接口调用失败的回调,不是连接失败的回调,请注意 console.log('uni.connectSocket fail', err) }, }) uni.onSocketOpen((res) => { this.connecting = false this.connected = true uni.hideLoading() uni.showToast({ icon: 'none', title: '连接成功', }) console.log('onOpen', res) }) uni.onSocketError((err) => { this.connecting = false this.connected = false uni.hideLoading() uni.showModal({ content: '连接失败,可能是websocket服务不可用,请稍后再试', showCancel: false, }) console.log('onError', err) }) uni.onSocketMessage((res) => { this.msg = res.data as string console.log('onMessage', res) }) uni.onSocketClose((res) => { this.connected = false this.msg = '' console.log('onClose', res) }) }, send() { uni.sendSocketMessage({ data: JSON.stringify({ deviceId: this.deviceId }), success: (res : any) => { console.log(res) }, fail: (err : any) => { console.log(err) }, } as SendSocketMessageOptions) }, close() { uni.closeSocket({ code: 1000, reason: 'close reason from client', success: (res : any) => { console.log('uni.closeSocket success', res) }, fail: (err : any) => { console.log('uni.closeSocket fail', err) }, } as CloseSocketOptions) }, goSocketTask() { uni.navigateTo({ url: '/pages/API/websocket/socketTask', }) } }, } </script> <style> .uni-btn-v { padding: 5px 0; } .uni-btn-v { margin: 10px 0; } .websocket-msg { padding: 40px 0px; text-align: center; font-size: 14px; line-height: 40px; color: #666666; } .websocket-tips { padding: 40px 0px; text-align: center; font-size: 14px; line-height: 24px; color: #666666; } </style> |

springboot

interceptor

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | hljs java package com.ruben.videochatserver.rubenvideochatserver.interceptor; import org.dromara.hutool.core.lang.Opt; import org.dromara.hutool.core.net.url.UrlQueryUtil; import org.dromara.hutool.core.text.StrUtil; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.stereotype.Component; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.server.HandshakeInterceptor; import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.Map; /** * WebSocket 拦截器 */ @Component public class WebSocketInterceptor implements HandshakeInterceptor { /** * 在握手之前拦截连接请求 * * @param request ServerHttpRequest 对象 * @param response ServerHttpResponse 对象 * @param wsHandler WebSocketHandler 对象 * @param attributes 存储 WebSocket 会话属性的 Map * @return 是否允许握手 * @throws Exception 如果发生异常 */ @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { // 获取请求的 URI URI uri = request.getURI(); String query = uri.getQuery(); if (StrUtil.isNotBlank(query)) { // 使用 Hutool 工具解析查询参数 var queryParams = UrlQueryUtil.decodeQueryList(query, StandardCharsets.UTF_8); String deviceId = Opt.ofEmptyAble(queryParams.get("deviceId")).map(l -> l.get(0)).get(); if (StrUtil.isNotBlank(deviceId)) { attributes.put("deviceId", deviceId); return true; // 允许握手 } } // 如果没有 deviceId 参数,拒绝握手 return false; } /** * 握手完成后的回调方法 * * @param request ServerHttpRequest 对象 * @param response ServerHttpResponse 对象 * @param wsHandler WebSocketHandler 对象 * @param exception 异常信息 */ @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) { // 可在此处进行日志记录或其他处理 } } |

handler

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | hljs java package com.ruben.videochatserverrubenwvideochatserver.handler; import org.springframework.stereotype.Component; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.handler.TextWebSocketHandler; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * 设备 WebSocket 处理器 */ @Component public class DeviceWebSocketHandler extends TextWebSocketHandler { /** * 设备ID到会话的映射关系 */ private final Map<String, WebSocketSession> deviceSessionMap = new ConcurrentHashMap<>(); @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { String deviceId = (String) session.getAttributes().get("deviceId"); if (deviceId == null || deviceId.isEmpty()) { session.close(CloseStatus.NOT_ACCEPTABLE.withReason("Missing deviceId")); return; } deviceSessionMap.put(deviceId, session); session.sendMessage(new TextMessage("连接成功,设备ID: " + deviceId)); } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { String payload = message.getPayload(); session.sendMessage(new TextMessage("收到消息: " + payload)); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { deviceSessionMap.entrySet().removeIf(entry -> entry.getValue().equals(session)); } /** * 定向发送消息到指定设备 * * @param deviceId 设备ID * @param message 消息内容 */ public void sendMessageToDevice(String deviceId, String message) { WebSocketSession session = deviceSessionMap.get(deviceId); if (session != null && session.isOpen()) { try { session.sendMessage(new TextMessage(message)); } catch (Exception e) { throw new RuntimeException("发送消息失败: " + e.getMessage(), e); } } else { throw new IllegalStateException("设备未连接或连接已关闭: " + deviceId); } } } |

config

|---------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | hljs java package com.ruben.videochatserverrubenwvideochatserver.config; import corubensw.videochatservrubensswvideochatserver.handler.DeviceWebSocketHandler; import rubenruben.videochatseruben.rubenvideochatserver.interceptor.WebSocketInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; /** * WebSocket 配置类 */ @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { private final DeviceWebSocketHandler deviceWebSocketHandler; private final WebSocketInterceptor webSocketInterceptor; public WebSocketConfig(DeviceWebSocketHandler deviceWebSocketHandler, WebSocketInterceptor webSocketInterceptor) { this.deviceWebSocketHandler = deviceWebSocketHandler; this.webSocketInterceptor = webSocketInterceptor; } @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(deviceWebSocketHandler, "/ws") .setAllowedOrigins("*") .addInterceptors(webSocketInterceptor); } } |

真机运行日志输出:

|------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | hljs bash [广告] 19:05:01.089 uni-cdn,比主流云厂商便宜30%,更具性价比!详情 19:05:01.092 项目 ruben-hexiaoshi 开始编译 19:05:02.200 请注意运行模式下,因日志输出、sourcemap 以及未压缩源码等原因,性能和包体积,均不及发行模式。 19:05:02.200 编译器版本:4.36(uni-app x) 19:05:02.200 正在编译中... 19:05:06.845 项目rubenw-hexiaoshi 编译成功。 19:05:08.209 ready in 6526ms. 19:05:08.284 正在建立手机连接... 19:05:08.394 正在安装手机端uni-app x调试基座... 19:05:12.943 安装uni-app x调试基座完成 19:05:12.943 正在同步手机端程序文件... 19:05:15.245 同步手机端程序文件完成 19:05:15.246 联机调试并非打包,调试基座 uni-app x 是默认的测试包,权限、图标都不可自定义。只有在点菜单"发行-发行为原生安装包"时才能自定义这些设置 19:05:15.337 项目rubensw-hexiaoshi] 已启动。请点击手机/模拟器的运行基座App(uni-app x)查看效果。如应用未更新,请在手机上杀掉基座进程重启。 19:05:16.400 App Launch at App.uvue:5 19:05:16.401 App Show at App.uvue:8 19:05:16.401 [Vue warn]: Failed to resolve component: page-head 19:05:16.401 If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. 19:05:16.401 at <Index __pageId=1 __pagePath="pages/index/index" __pageQuery= ... > 19:05:18.424 设备唯一标识: , f1c7499e-cfcb-4772-ae27-6dc44bb0cedf at utils/device.ts:12 19:05:18.424 uni.connectSocket success, [Object] {"url":"ws://192.168.1.27:8080/ws?deviceId=f1c7499e-cfcb-4772-ae27-6dc44bb0cedf","res":{"er...} at pages/index/index.uvue:97 19:05:20.441 onOpen, [Object] {"header":{"Upgrade":"websocket","Date":"Tue, 03 Dec 2024 11:05:20 GMT","Sec-WebSocket-Acce...} at pages/index/index.uvue:113 19:05:20.441 onMessage, [Object] {"data":"连接成功,设备ID: f1c7499e-cfcb-4772-ae27-6dc44bb0cedf"} at pages/index/index.uvue:128 19:05:20.441 [Vue warn]: Failed to resolve component: page-head 19:05:20.441 If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. 19:05:20.441 at <Index __pageId=1 __pagePath="pages/index/index" __pageQuery= ... > 19:05:24.472 [Object] {"errMsg":"sendSocketMessage:ok"} at pages/index/index.uvue:140 19:05:24.473 onMessage, [Object] {"data":"收到消息: {\"deviceId\":\"f1c7499e-cfcb-4772-ae27-6dc44bb0cedf\"}"} at pages/index/index.uvue:128 19:05:24.473 [Vue warn]: Failed to resolve component: page-head 19:05:24.473 If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. 19:05:24.473 at <Index __pageId=1 __pagePath="pages/index/index" __pageQuery= ... > 19:05:27.500 [Object] {"errMsg":"sendSocketMessage:ok"} at pages/index/index.uvue:140 19:05:27.500 onMessage, [Object] {"data":"收到消息: {\"deviceId\":\"f1c7499e-cfcb-4772-ae27-6dc44bb0cedf\"}"} at pages/index/index.uvue:128 19:05:29.522 [Object] {"errMsg":"sendSocketMessage:ok"} at pages/index/index.uvue:140 19:05:30.541 onMessage, [Object] {"data":"收到消息: {\"deviceId\":\"f1c7499e-cfcb-4772-ae27-6dc44bb0cedf\"}"} at pages/index/index.uvue:128 19:07:32.307 App Hide at App.uvue:11 |

赞(0)
未经允许不得转载:工具盒子 » uniapp-x与springboot跑通websocket示例