websocket 简介
websocket 协议是在 http 协议上的一种补充协议,是 html5 的新特性,是一种持久化的协议。
加入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
配置
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; @Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
核心代码
接下来最核心的类其实就是提供一个前后端交互的类实现消息的接收推送。
-
@ServerEndpoint(value = "/wsdemo") 前端通过此 URI 和后端交互,建立连接
-
@OnOpen websocket 建立连接的注解,前端触发上面 URI 时会进入此注解标注的方法
-
@OnClose 关闭连接,销毁 session
-
@OnMessage 收到前端传来的消息后执行的方法
import org.springframework.stereotype.Component; import javax.websocket.*; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.concurrent.CopyOnWriteArraySet; @ServerEndpoint(value = "/wsdemo") @Component public class MyWebSocket { private static int onlineCount = 0; private static CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<MyWebSocket>(); private Session session; @OnOpen public void onOpen(Session session) { this.session = session; webSocketSet.add(this); addOnlineCount(); System.out.println("有新连接加入!当前在线人数为" + getOnlineCount()); try { sendMessage("连接已建立成功."); } catch (Exception e) { System.out.println("IO异常"); } } @OnClose public void onClose() { webSocketSet.remove(this); subOnlineCount(); System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount()); } @OnMessage public void onMessage(String message, Session session) { System.out.println("来自客户端的消息:" + message); } @OnError public void onError(Session session, Throwable error) { System.out.println("发生错误"); error.printStackTrace(); } public void sendMessage(String message) throws IOException { this.session.getBasicRemote().sendText(message); } public static synchronized int getOnlineCount() { return onlineCount; } public static synchronized void addOnlineCount() { MyWebSocket.onlineCount++; } public static synchronized void subOnlineCount() { MyWebSocket.onlineCount--; } public Session getSession() { return session; } public void setSession(Session session) { this.session = session; } public static CopyOnWriteArraySet<MyWebSocket> getWebSocketSet() { return webSocketSet; } public static void setWebSocketSet(CopyOnWriteArraySet<MyWebSocket> webSocketSet) { MyWebSocket.webSocketSet = webSocketSet; } }
定时任务
用于测试给前端发送消息
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.io.IOException; import java.util.Date; import java.util.concurrent.CopyOnWriteArraySet; @Component @EnableScheduling public class TimeTask { private static Logger logger = LoggerFactory.getLogger(TimeTask.class); @Scheduled(cron = "0/5 * * * * ?") public void test() { System.err.println("********* 定时任务执行 **************"); CopyOnWriteArraySet<MyWebSocket> webSocketSet = MyWebSocket.getWebSocketSet(); int i = 0; webSocketSet.forEach(c -> { try { c.sendMessage(" 定时发送 " + new Date().toLocaleString()); } catch (IOException e) { e.printStackTrace(); } }); System.err.println("/n 定时任务完成......."); } }
前端页面
<!DOCTYPE HTML> <html> <head> <title> My WebSocket </title> </head> <body> Welcome <br/> <input id="text"/> <button onclick="send()"> Send</button> <button onclick="closeWebSocket()"> Close</button> <div id="message"></div> </body> <script type="text/javascript"> var websocket = null; //判断当前浏览器是否支持WebSocket ,主要此处要更换为自己的地址 if ('WebSocket' in window) { websocket = new WebSocket("ws://localhost:8081/wsdemo"); } 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>
文章来源:https://mp.weixin.qq.com/s/9AJ0w0oqvOrQ3RgxLtmWLg
源码:https://gitee.com/caoyeoo0/xc-springboot/tree/websokcet/