问题描述
为了让更好地压榨cpu的性能,通常会使用多线程的方式异步地计算多个任务,这样前端发送计算请求之后,后端并不会等到任务计算结束才给前端返回数据,而是添加计算任务就立即返回 “计算任务添加计算成功” 。
后端
依赖
<!-- websocket --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> </dependency>
配置类
package com.dam.config.webSocket; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; @Configuration public class WebSocketConfig { /** * 注入一个ServerEndpointExporter,该Bean会自动注册使用@ServerEndpoint注解申明的websocket endpoint */ @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
组件
package com.dam.component; import com.dam.utils.JwtUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * @author websocket服务 */ @ServerEndpoint(value = "/shift-scheduling-calculate-service/imserver/{token}") @Component//将WebSocketServer注册为spring的一个bean public class WebSocketServer { private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class); /** * 记录当前在线连接的客户端的session */ public static final Map<String, Session> tokenAndSessionMap = new ConcurrentHashMap<>(); /** * 浏览器和服务端连接建立成功之后会调用这个方法 */ @OnOpen public void onOpen(Session session, @PathParam("token") String token) { tokenAndSessionMap.put(token, session); log.info("有新用户加入,username={}, 当前在线人数为:{}", JwtUtil.getUsername(token), tokenAndSessionMap.size()); } /** * 连接关闭调用的方法 */ @OnClose public void onClose(Session session, @PathParam("token") String token) { String username = JwtUtil.getUsername(token); tokenAndSessionMap.remove(username); log.info("有一连接关闭,移除username={}的用户session, 当前在线人数为:{}", username, tokenAndSessionMap.size()); } /** * 发生错误的时候会调用这个方法 */ @OnError public void onError(Session session, Throwable error) { log.error("发生错误"); error.printStackTrace(); } /** * 服务端发送消息给客户端 */ public void sendMessage(String message, Session toSession) { try { log.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message); toSession.getBasicRemote().sendText(message); } catch (Exception e) { log.error("服务端发送消息给客户端失败", e); } } }
使用(服务端给客户端发送消息)
计算完成给客户端发送消息
前端
初始化webSocket对象的方法
/** * 初始化webSocket */ webSocketInit() { let _this = this; if (typeof (WebSocket) == "undefined") { console.log("您的浏览器不支持WebSocket协议"); } else { console.log("您的浏览器支持WebSocket协议"); let socketUrl = "ws://localhost:6001/shift-scheduling-calculate-service/imserver/" + getToken(); if (socket != null) { socket.close(); socket = null; } // 开启一个websocket服务 socket = new WebSocket(socketUrl); //打开日志事件 socket.onopen = function () { console.log("websocket已打开"); }; //浏览器端收消息,获得从服务端发送过来的文本消息 socket.onmessage = function (msg) { // console.log("收到数据====" + msg.data); // msg.data={"taskId":15,"isSuccess":1} let mesage = JSON.parse(msg.data); //修改任务的状态 _this.editTaskStatus(mesage.taskId, mesage.isSuccess); }; //关闭事件 socket.onclose = function () { console.log("websocket已关闭"); }; //发生了错误事件 socket.onerror = function () { console.log("websocket发生了错误"); } } },