Spring boot集成websocket通信
介绍
websocket是一个持久化的协议,实现了浏览器与服务器的全双工通信。不再像http那样,只有在浏览器发出request之后才有response,websocket能实现服务器主动向浏览器发出消息。
Spring boot项目集成实现
在pom.xml中添加依赖
1234<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>
添加一个单例bean配置,名为ServerEndpointExporter
1234567public class WebSocketConfig {public ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}}websocket监听实现示例
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118"/websocket")(value =public class WebSocketServer {private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。private static int onlineCount = 0;//会话保存集合private static ConcurrentSkipListMap<String, WebSocketServer> webSocketMap = new ConcurrentSkipListMap<>();//企业编号 作为保存会话的keyprivate String enterpriseNo;//与某个客户端的连接会话,需要通过它来给客户端发送数据private Session session;/*** 会话建立* @param session*/public void onOpen(Session session) {List<String> params = session.getRequestParameterMap().get("enterpriseNo");if (params != null && (this.enterpriseNo = params.get(0)) != null && this.enterpriseNo.length() > 0) {//保存会话this.session = session;webSocketMap.put(this.enterpriseNo, this);addOnlineCount(); //在线数加1log.info("有新连接加入!当前在线人数为" + getOnlineCount());} else {// 如果参数不正确,则不保存会话try {session.close();} catch (IOException e) {log.error(e.getMessage(),e.getCause());e.printStackTrace();}}}/*** 连接关闭调用的方法*/public void onClose() {webSocketMap.remove(this.enterpriseNo);subOnlineCount(); //在线数减1log.info("有一连接关闭!当前在线人数为" + getOnlineCount());}/*** 接收消息* @param message* @param session*/public void onMessage(String message, Session session) {try {log.info("接收到会话:\""+session.getId()+"\"发送的信息、消息内容:"+message);//数据转换成对象} catch (Exception e) {log.error(e.getMessage(),e.getCause());e.printStackTrace();}}/*** 异常记录* @param session* @param error*/public void onError(Session session, Throwable error) {log.error(error.getMessage(), error.getCause());}/*** 执行向浏览器发送消息动作* @param message* @throws IOException*/public void sendMessage(String message) throws IOException {this.session.getBasicRemote().sendText(message);}/*** 向指定会话发送消息* @param enterpriseNo* @param message*/public static boolean sendInfo(String enterpriseNo,String message) {try {WebSocketServer wss = webSocketMap.get(enterpriseNo);if (wss!=null) {wss.sendMessage(message);return true;}} catch (IOException e) {e.printStackTrace();}return false;}public static synchronized int getOnlineCount() {return onlineCount;}public static synchronized void addOnlineCount() {WebSocketServer.onlineCount++;}public static synchronized void subOnlineCount() {WebSocketServer.onlineCount--;}}HTML页面代码示例
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869<html><head><base href="http://localhost:8080/"><title>My WebSocket</title></head><body>Welcome<br/><input id="text" type="text"/><button onclick="send()">Send</button><button onclick="closeWebSocket()">Close</button><div id="message"></div></body><script type="text/javascript">var websocket = null;//判断当前浏览器是否支持WebSocketif ('WebSocket' in window) {websocket = new WebSocket("ws://localhost:8080/websocket");}else {alert('Not support websocket')}//连接发生错误的回调方法websocket.onerror = function () {setMessageInnerHTML("error");};//连接成功建立的回调方法websocket.onopen = function (event) {setMessageInnerHTML("open");}//接收到消息的回调方法websocket.onmessage = function (event) {setMessageInnerHTML(event.data);}//连接关闭的回调方法websocket.onclose = function () {setMessageInnerHTML("close");}//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。window.onbeforeunload = function () {websocket.close();}//将消息显示在网页上function setMessageInnerHTML(innerHTML) {document.getElementById('message').innerHTML += innerHTML + '<br/>';}//关闭连接function closeWebSocket() {websocket.close();}//发送消息function send() {var message = document.getElementById('text').value;websocket.send(message);}</script></html>
接下来便能直接启动websocket进行访问了,具体的扩展可以根据业务需求进行增加。
其实websocket就是基于http协议的升级,在http的headers中有一个header名为Upgrade,用来对http协议进行升级,从而换用其他的协议,在本例中,为Upgrade:websocket