websocket 是一种在单个 tcp 连接上进行全双工通信的协议,已被 w3c 定为标准。使用 websocket 可以使得客户端和服务器之间的数据交换变得更加简单。在 websocket 协议中,浏览器和服务器只需要完成一次握手,两者之间就可以直接创建持久性的连接,并进行双向数据传输。
特点
websocket 使用时需要先创建连接,这使得 websocket 成为一种有状态的协议,在之后的通信过程中可以省略部分状态信息(例如身份认证等)。
websocket 连接在端口 80(ws)或者 443(wss)上创建,与 http 使用的端口相同,这样,基本上所有的防火墙都不会阻止 websocket 连接。
websocket 使用 http 协议进行握手,因此它可以自然而然地集成到网络浏览器和 http 服务器中,而不需要额外的成本。
心跳消息(ping 和 pong)将被反复的发送,进而保持 websocket 连接一直处于活跃状态。
使用该协议,当消息启动或者到达的时候,服务端和客户端都可以知道。
websocket 连接关闭时将发送一个特殊的关闭消息。
websocket 支持跨域,可以避免 ajax 的限制。
http 规范要求浏览器将并发连接数限制为每个主机名两个连接,但是当我们使用 websocket 的时候,当握手完成之后,该限制就不存在了,因为此时的连接已经不再是 http 连接了。
websocket 协议支持扩展,用户可以扩展协议,实现部分自定义的子协议。
websocket 拥有更好的二进制支持以及更好的压缩效果。
一、添加依赖
<dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-websocket</artifactid></dependency>
二、配置 websocket
spring 框架提供了基于 websocket 的 stomp 支持,stomp 是一个简单的可互操作的协议,通常被用于通过中间服务器在客户端之间进行异步消息传递。
@configuration@enablewebsocketmessagebrokerpublic class websocketconfig implements websocketmessagebrokerconfigurer { @override public void configuremessagebroker(messagebrokerregistry config) { // 设置消息代理的前缀,如果消息的前缀为/topic,就会将消息转发给消息代理(broker) // 再由消息代理广播给当前连接的客户端 config.enablesimplebroker(/topic); // 下面方法可以配置一个或多个前缀,通过这些前缀过滤出需要被注解方法处理的消息。 // 例如这里表示前缀为/app的destination可以通过@messagemapping注解的方法处理 // 而其他 destination(例如/topic/queue)将被直接交给 broker 处理 config.setapplicationdestinationprefixes(/app); } @override public void registerstompendpoints(stompendpointregistry registry) { // 定义一个前缀为/chart的endpoint,并开启 sockjs 支持。 // sockjs 可以解决浏览器对websocket的兼容性问题,客户端将通过这里配置的url建立websocket连接 registry.addendpoint(/chat).withsockjs(); }}
三、服务端代码
根据上面 websocketconfig 的配置,@messagemapping(/hello) 注解的方法将用来接收“/app/hello”路径发送来的消息,在注解方法中对消息进行处理后,再将消息转发到 @sendto 定义的路径上。而 @sendto 路径是一个前缀为“/topic”的路径,因此该消息被交给消息代理 broker,再由 broker 进行广播。
@controllerpublic class democontroller { @messagemapping(/hello) @sendto(/topic/greetings) public message greeting(message message) throws exception { return message; }}
@datapublic class message { private string name; private string content;}
四、前端代码
在 resources/static 目录下创建 chat.html 页面作为聊天页面。
<!doctype html><html lang="en"><head> <meta charset="utf-8"> <title>群聊</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/sockjs-client/1.1.2/sockjs.min.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script> <script> var stompclient = null; // 根据是否已连接设置页面元素状态 function setconnected(connected) { $(#connect).prop(disabled, connected); $(#disconnect).prop(disabled, !connected); if (connected) { $(#conversation).show(); $(#chat).show(); } else { $(#conversation).hide(); $(#chat).hide(); } $(#greetings).html(); } // 建立一个websocket连接 function connect() { // 用户名不能为空 if (!$(#name).val()) { return; } // 首先使用 sockjs 建立连接 var socket = new sockjs('/chat'); // 然后创建一个stomp实例发起连接请求 stompclient = stomp.over(socket); // 连接成功回调 stompclient.connect({}, function (frame) { // 进行页面设置 setconnected(true); // 订阅服务端发送回来的消息 stompclient.subscribe('/topic/greetings', function (greeting) { // 将服务端发送回来的消息展示出来 showgreeting(json.parse(greeting.body)); }); }); } // 断开websocket连接 function disconnect() { if (stompclient !== null) { stompclient.disconnect(); } setconnected(false); } // 发送消息 function sendname() { stompclient.send(/app/hello, {}, json.stringify({'name': $(#name).val(),'content':$(#content).val()})); } // 将服务端发送回来的消息展示出来 function showgreeting(message) { $(#greetings) .append(<div> + message.name+:+message.content + </div>); } // 页面加载后进行初始化动作 $(function () { $( #connect ).click(function() { connect(); }); $( #disconnect ).click(function() { disconnect(); }); $( #send ).click(function() { sendname(); }); }); </script></head><body><div> <label for="name">请输入用户名:</label> <input type="text" id="name" placeholder="用户名"></div><div> <button id="connect" type="button">连接</button> <button id="disconnect" type="button" disabled="disabled">断开连接</button></div><div id="chat" > <div> <label for="name">请输入聊天内容:</label> <input type="text" id="content" placeholder="聊天内容"> </div> <button id="send" type="button">发送</button> <div id="greetings"> <div id="conversation" >群聊进行中...</div> </div></div></body></html>
sockjs 是一个浏览器javascript库,提供类似于websocket的对象。sockjs为您提供了一个一致的,跨浏览器的javascript api,该api在浏览器和web服务器之间创建了低延迟,全双工,跨域的通信通道。
stomp 即simple (or streaming) text orientated messaging protocol,简单(流)文本定向消息协议,它提供了一个可互操作的连接格式,允许stomp客户端与任意stomp消息代理(broker)进行交互。
@sendto 注解,该注解将方法处理过的消息转发到 broker,再由 broker 进行消息广播。
五、验证结果
我们请求地址:http://127.0.0.1:8086/chat.html
登录用户:piao
登录用户:admin
以上就是springboot怎么使用websocket实现群发消息的详细内容。