赞
踩
<!-- websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
@Configuration
public class WebSocketConfig {
/**
* 注入一个ServerEndpointExporter,该Bean会自动注册使用@ServerEndpoint注解申明的websocket endpoint
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
@ServerEndpoint(value = "/imserver/{id}") @Component public class WebSocketServer { /**concurrent包的线程安全Set,用来存放每个客户端对应的WebSocket对象。*/ private static ConcurrentHashMap<String,WebSocketServer> webSocketMap = new ConcurrentHashMap<>(); /**与某个客户端的连接会话,需要通过它来给客户端发送数据*/ private Session session; /**接收id*/ private String id = ""; /** * 连接建立成功调用的方法 */ @OnOpen public void onOpen(Session session, @PathParam("id") String id) { this.session = session; this.id=id; // 如果有则重置 if(webSocketMap.containsKey(id)){ webSocketMap.remove(id); //加入Map中 webSocketMap.put(id,this); }else{ //加入Map中 webSocketMap.put(id,this); } System.out.println(id + " 连接"); sendMessage("连接成功"); } /** * 连接关闭调用的方法 */ @OnClose public void onClose() { webSocketMap.remove(id); System.out.println(id+" 连接关闭"); } /** * 收到客户端消息后调用的方法 * 后台收到客户端发送过来的消息 **/ @OnMessage public void onMessage(String message, Session session) { System.out.println("用户消息:"+id+"\n报文:"+message); //可以群发消息 //消息保存到数据库、redis if(StringUtils.isNotBlank(message)){ try { //解析发送的报文 JSONObject jsonObject = JSONObject.parseObject(message); //追加发送人(防止串改) jsonObject.put("fromid",this.id); String toid=jsonObject.getString("toid"); //传送给对应toid用户的websocket if(StringUtils.isNotBlank(toid)&&webSocketMap.containsKey(toid)){ webSocketMap.get(toid).sendMessage(message); }else{ //否则不在这个服务器上,发送到mysql或者redis System.out.println("请求的id:"+toid+"不在该服务器上"); } }catch (Exception e){ e.printStackTrace(); } } } /** * 遇到错误调用的方法 */ @OnError public void onError(Session session, Throwable error) { System.out.println("用户错误:"+this.id+",原因:"+error.getMessage()); error.printStackTrace(); } /** * 实现服务器主动推送消息给客户端 */ public void sendMessage(String message) { try { this.session.getBasicRemote().sendText(message); } catch (IOException e) { e.printStackTrace(); } } /** *发送自定义消息 **/ public static void sendInfo(String id, String message) { System.out.println("发送消息到:"+id+",报文:"+message); if(StringUtils.isNotBlank(id) && webSocketMap.containsKey(id)){ webSocketMap.get(id).sendMessage(message); }else{ System.out.println("id:"+id+",不存在!"); } } }
data(){ return{ // 用于记录已经创建的websocket,防止重复创建 webSocketIdSet: new Set(), // 用于保存多组websocket websocketMap: new Map() } }, methods:{ // 连接webSocket connectWebSocket(webSocketId) { if (!this.webSocketIdSet.has(webSocketId)) { // 防止重复连接 this.webSocketIdSet.add(webSocketId) if ('WebSocket' in window) { console.log('connectWebSocket') const url = "自定义url" const websocket = new WebSocket('ws://' + url + '/imserver/' + webSocketId) this.websocketMap.set(webSocketId, websocket) this.initWebSocket(webSocketId) } else { alert('当前浏览器不支持WebSocket!!!') console.log('当前浏览器不支持WebSocket') } } }, initWebSocket(webSocketId) { // 连接错误 this.websocketMap.get(webSocketId).onerror = this.setErrorMessage // 连接成功 this.websocketMap.get(webSocketId).onopen = this.setOnopenMessage // 收到消息的回调 this.websocketMap.get(webSocketId).onmessage = this.setOnmessageMessage // 连接关闭的回调 this.websocketMap.get(webSocketId).onclose = this.setOncloseMessage // 监听窗口关闭事件,当窗口关闭时,主动去关闭所有websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。 window.onbeforeunload = this.onbeforeunload }, // 业务处理 setOnmessageMessage(event) { console.log('返回的数据', event.data) // 获取webSocketId const url = event.target.url.toString() const webSocketId = url.substring(url.lastIndexOf('/') + 1, url.indexOf('?')) console.log("webSocketId",webSocketId) }, setErrorMessage(event) { const url = event.target.url.toString() const webSocketId = url.substring(url.lastIndexOf('/') + 1, url.indexOf('?')) console.log('WebSocket连接发生错误,状态码:' + this.websocketMap.get(webSocketId).readyState) }, setOnopenMessage(event) { const url = event.target.url.toString() const webSocketId = url.substring(url.lastIndexOf('/') + 1, url.indexOf('?')) console.log('WebSocket连接成功,状态码:' + this.websocketMap.get(webSocketId).readyState) }, setOncloseMessage() { console.log('WebSocket连接关闭') }, onbeforeunload() { this.closeWebSocket(null) }, // 当参数为空时关闭所有webSocket,否则关闭键为webSocketId的webSocket closeWebSocket(webSocketId) { if (webSocketId === null) { this.websocketMap.forEach((k, v) => { if (v !== null) { v.close() this.websocketMap.delete(k) this.webSocketIdSet.delete(k) } }) } else { if (this.websocketMap.get(webSocketId) !== null) { this.websocketMap.get(webSocketId).close() this.websocketMap.delete(webSocketId) this.webSocketIdSet.delete(webSocketId) } } }
在异步请求前创建websocket,在后端用WebSocketServer.sendInfo(id,message)将信息从服务端发送给客户端,然后前端会通过setOnmessageMessage(event)来处理后端发来的信息。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。