简单的websocket demo
使用websocket有两种方式:1是使用sockjs,2是使用h5的标准。使用Html5标准自然更方便简单,所以记录的是配合h5的使用方法。
pom
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
使用@ServerEndpoint创立websocket endpoint
首先要注入ServerEndpointExporter,这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint。要注意,如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。@Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter(){ return new ServerEndpointExporter(); } }
接下来就是写websocket的具体实现类,直接上代码:
@Component @ServerEndpoint("/websocket") public class MyWebSocket { //与某个客户端的连接会话,需要通过它来给客户端发送数据 private Session session; //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。 private static CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<MyWebSocket>(); @OnOpen public void onOpen(Session session){ this.session = session; webSocketSet.add(this); System.out.println("创建连接:第"+webSocketSet.size()); } @OnClose public void onClose(){ webSocketSet.remove(this); System.out.println("关闭连接"); } @OnMessage public void onMessage(String message){ System.out.println("接受客户端消息:"+message); } /** * 群发消息 */ public void sendMessage(String message){ for (MyWebSocket myWebSocket : webSocketSet){ try { myWebSocket.session.getBasicRemote().sendText(message); } catch (IOException e) { e.printStackTrace(); } } } //单发消息可以在群发的基础上改造 }
使用springboot的唯一区别是要@Component声明下,而使用独立容器是由容器自己管理websocket的,但在springboot中连容器都是spring管理的。
虽然@Component默认是单例模式的,但springboot还是会为每个websocket连接初始化一个bean,所以可以用一个静态set保存起来。前端代码
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;" name="viewport" /> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>主页</title> </head> <body> <script type="text/javascript" th:inline="javascript"> var websocket = null; if('WebSocket' in window){ //127.0.0.1:8080 是的项目请求地址 websocket是对应@ServerEndpoint("/websocket")里的值 合起来就是请求websocket地址 websocket = new WebSocket('ws://127.0.0.1:8080/websocket'); }else{ alert("该浏览器不支持websocket!") } websocket.onopen = function (event) { console.log("建立连接"); } websocket.onclose = function (event) { console.log("关闭连接"); } websocket.onmessage = function (event) { console.log("接受消息:"+event.data); //模拟发送信息给服务端 websocket.send("我已经接受到信息啦!") } websocket.onerror = function (event) { console.log("出现了错误") } window.onbeforeunload = function () { websocket.onclose(); } </script> </body> </html>
测试方法
@RestController @RequestMapping("/testWebSocketSend") public class TestWebSocketSendController { @Autowired private MyWebSocket myWebSocket; @GetMapping("send") public String send(@RequestParam("message") String message){ //todo 其他业务 //websocket服务 myWebSocket.sendMessage(message); return "成功"; } }
打开主页面 127.0.0.1:8080/index.html
浏览器请求127.0.0.1:8080/testWebSocketSend/se... 我之前写的controller地址
服务端接受客户端的消息打印
本作品采用《CC 协议》,转载必须注明作者和本文链接