本文共 5641 字,大约阅读时间需要 18 分钟。
在 pom.xml 中添加 WebSocket 和 Thymeleaf 组件:
org.springframework.boot spring-boot-starter-websocket org.springframework.boot spring-boot-starter-thymeleaf
在 WebSocketConfig 类中启用 WebSocket 支持:
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.socket.server.standard.ServerEndpointExporter;@Configurationpublic class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); }} 在 WebSocketServerConfig 类中实现 WebSocket 服务器功能:
import javax.websocket.OnClose;import javax.websocket.OnError;import javax.websocket.OnMessage;import javax.websocket.OnOpen;import javax.websocket.PathParam;import javax.websocket.server.ServerEndpoint;import com.alibaba.fastjson.JSONObject;import org.springframework.stereotype.Component;import org.slf4j.Logger;import org.slf4j.LoggerFactory;@Component@ServerEndpoint("/imserver/{userId}")public class WebSocketServerConfig { private static Logger log = LoggerFactory.getLogger(WebSocketServerConfig.class); private static ConcurrentHashMap webSocketMap = new ConcurrentHashMap<>(); private Session session; private String userId; @OnOpen public void onOpen(Session session, @PathParam("userId") String userId) { this.session = session; this.userId = userId; if (webSocketMap.containsKey(userId)) { webSocketMap.remove(userId); } webSocketMap.put(userId, this); addOnlineCount(); sendMessage("我在线上"); } @OnClose public void onClose() { if (webSocketMap.containsKey(userId)) { webSocketMap.remove(userId); subOnlineCount(); } } @OnMessage public void onMessage(String message, Session session) { JSONObject jsonObject = JSON.parseObject(message); String toUserId = jsonObject.getString("toUserId"); if (!StringUtils.isBlank(toUserId) && webSocketMap.containsKey(toUserId)) { WebSocketServerConfig.sendInfo(message, toUserId); } else { log.error("用户 " + toUserId + " 不在线!"); } } @OnError public void onError(Session session, Throwable error) { log.error("用户错误:" + this.userId + ", 原因:" + error.getMessage()); error.printStackTrace(); } public static void sendMessage(String message, @PathParam("userId") String userId) throws IOException { WebSocketServerConfig.sendInfo(message, userId); } public static synchronized int getOnlineCount() { return onlineCount; } public static synchronized void addOnlineCount() { onlineCount++; } public static synchronized void subOnlineCount() { onlineCount--; }} 在 HTML 页面中实现 WebSocket 连接:
var socket;function openSocket() { if (typeof WebSocket === "undefined") { alert("您的浏览器不支持 WebSocket"); } else { var socketUrl = "ws://localhost:10106/imserver/" + $("#userId").val(); socket = new WebSocket(socketUrl); socket.onopen = function() { console.log("WebSocket 已打开"); }; socket.onmessage = function(msg) { var contentText = msg.data; talking(contentText); }; socket.onclose = function() { console.log("WebSocket 已关闭"); }; socket.onerror = function() { console.log("WebSocket 发生了错误"); }; }} 实现消息发送功能:
function sendMessage() { if (typeof WebSocket === "undefined") { alert("您的浏览器不支持 WebSocket"); } else { var toUserId = $("#toUserId").val(); var message = JSON.stringify({ toUserId: toUserId, contentText: $("#contentText").val() }); socket.send(message); var username = $("#userId").val(); var sendhistory = $("#contentText").val(); document.getElementById("content").append(username + ":" + sendhistory + "\r\n"); document.getElementById("contentText").val(""); }}function talking(content) { var toUsername = document.getElementById("toUserId").value; document.getElementById("content").append(toUsername + ":" + content + "\r\n");} 实现接口发送消息:
import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.*;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class MsgController { @CrossOrigin(origins = "*", maxAge = 3600) @RequestMapping("/websocket") public class MsgController { @GetMapping("/instance/message") public String page() { return "websocket/chatpage"; } @RequestMapping(value = "/push/{toUserId}", method = RequestMethod.POST) public Map pushToWeb(@RequestBody Map params, @PathVariable String toUserId) throws IOException { String message = params.get("message"); WebSocketServerConfig.sendInfo(message, toUserId); Map returnMap = new HashMap<>(); returnMap.put("code", "200"); returnMap.put("msg", "成功发送消息"); return returnMap; } }} 在 HTML 页面中展示消息记录:
消息记录
通过以上配置和实现,可以实现一个基于 Spring Boot 的 WebSocket 实时消息系统,支持用户之间实时通信。
转载地址:http://npht.baihongyu.com/