Websocket详解
WebSocket 是一种支持双向通讯网络通信协议。
意思就是服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息
属于服务器推送技术的一种。
为什么需要 WebSocket?
了解计算机网络协议的人,应该都知道:HTTP 协议是一种无状态的、无连接的、单向的应用层协议。它采用了请求/响应模型。通信请求只能由客户端发起,服务端对请求做出应答处理。
这种通信模型有一个弊端:HTTP 协议无法实现服务器主动向客户端发起消息。
这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。大多数 Web 应用程序将通过频繁的异步 JavaScript 和 XML(AJAX)请求实现长轮询。轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。
因此,工程师们一直在思考,有没有更好的方法。WebSocket 就是这样发明的。WebSocket 连接允许客户端和服务器之间进行全双工通信,以便任一方都可以通过建立的连接将数据推送到另一端。WebSocket 只需要建立一次连接,就可以一直保持连接状态。这相比于轮询方式的不停建立连接显然效率要大大提高。
spring Boot整合websocket
第一步:导入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
第二步:编写WebSocketConfig配置类
@Configuration public class WebSocketConfig{ @Bean public ServerEndpointExporter serverEndpointExporter(){ return new ServerEndpointExporter(); } }
第三步:编写WebSocket类
//注册成组件 @Component //定义websocket服务器端,它的功能主要是将目前的类定义成一个websocket服务器端。注解的值将被用于监听用户连接的终端访问URL地址 @ServerEndpoint("/websocket") //如果不想每次都写private final Logger logger = LoggerFactory.getLogger(当前类名.class); 可以用注解@Slf4j;可以直接调用log.info @Slf4j public class WebSocket { //实例一个session,这个session是websocket的session private Session session; //存放websocket的集合(本次demo不会用到,聊天室的demo会用到) private static CopyOnWriteArraySet<WebSocket> webSocketSet = new CopyOnWriteArraySet<>(); //前端请求时一个websocket时 @OnOpen public void onOpen(Session session) { this.session = session; webSocketSet.add(this); log.info("【websocket消息】有新的连接, 总数:{}", webSocketSet.size()); } //前端关闭时一个websocket时 @OnClose public void onClose() { webSocketSet.remove(this); log.info("【websocket消息】连接断开, 总数:{}", webSocketSet.size()); } //前端向后端发送消息 @OnMessage public void onMessage(String message) { log.info("【websocket消息】收到客户端发来的消息:{}", message); } //新增一个方法用于主动向客户端发送消息 public static void sendMessage(String message) { for (WebSocket webSocket: webSocketSet) { log.info("【websocket消息】广播消息, message={}", message); try { webSocket.session.getBasicRemote().sendText(message); } catch (Exception e) { e.printStackTrace(); } } } }
第四步:改造控制器
编写一个接口方法,调用websocket的sendMessage方法
@Resourse Private WebSocket webSocket; public void sendMessage(String msg){ webSocket.sendMessage(msg); }
第五步:编写前端代码
<script type="text/javascript"> var websocket = null; //判断当前浏览器是否支持WebSocket if('WebSocket' in window){ websocket = new WebSocket("ws://localhost:8080/websocket"); }else{ alert('Not support websocket') } //连接发生错误的回调方法 websocket.onerror = function(){ setMessageInnerHTML("发生错误"); }; //连接成功建立的回调方法 websocket.onopen = function(event){ setMessageInnerHTML("建立连接"); } //接收到消息的回调方法 websocket.onmessage = function(event){ console.log(event.data) // setMessageInnerHTML(event.data); $(".progress-bar").attr("style","width:"+event.data+"%") } //连接关闭的回调方法 websocket.onclose = function(){ setMessageInnerHTML("关闭连接"); } //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。 window.onbeforeunload = function(){ alert("已关闭连接"); websocket.close(); } //将消息显示在网页上 function setMessageInnerHTML(innerHTML){ document.getElementById('message').innerHTML += innerHTML + '<br/>'; } //关闭连接 function closeWebSocket(){ alert("已关闭连接"); websocket.close(); } </script>
解释:
1、
var websocket = null;
//判断当前浏览器是否支持WebSocket
if('WebSocket' in window){ websocket = new WebSocket("ws://localhost:8089/websocket"); }else{ alert('Not support websocket') }
首先建立websocket连接。
注意:此处的地址的ws://是固定写法,后面加上你的ip+端口+WebSocket的ServerEndpoint注解配置的路径。
2、
//连接发生错误的回调方法 websocket.onerror = function(){ setMessageInnerHTML("发生错误"); }; //连接成功建立的回调方法 websocket.onopen = function(event){ setMessageInnerHTML("建立连接"); } //接收到消息的回调方法 websocket.onmessage = function(event){ console.log(event.data) // setMessageInnerHTML(event.data); $(".progress-bar").attr("style","width:"+event.data+"%") } //连接关闭的回调方法 websocket.onclose = function(){ setMessageInnerHTML("关闭连接"); }
都是websocket的固定写法,几个回调函数。
最后设置一个发送按钮请求控制器方法,到此整合完毕。
0条评论
点击登录参与评论