一、WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。
二、长久以来, 创建实现客户端和用户端之间双工通讯的web app都会造成HTTP轮询的滥用: 客户端向主机不断发送不同的HTTP呼叫来进行询问。
这会导致一系列的问题:
1.服务器被迫为每个客户端使用许多不同的底层TCP连接:一个用于向客户端发送信息,其它用于接收每个传入消息。
2.有些协议有很高的开销,每一个客户端和服务器之间都有HTTP头。
3.客户端脚本被迫维护从传出连接到传入连接的映射来追踪回复。
一个更简单的解决方案是使用单个TCP连接双向通信。 这就是WebSocket协议所提供的功能。 结合WebSocket API ,WebSocket协议提供了一个用来替代HTTP轮询实现网页到远程主机的双向通信的方法。
它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于
服务器推送技术的一种。
三、特点:
(1)建立在 TCP 协议之上,服务器端的实现比较容易。
(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
(3)数据格式比较轻量,性能开销小,通信高效。
(4)可以发送文本,也可以发送二进制数据。
(5)没有同源限制,客户端可以与任意服务器通信。
(6)协议标识符是ws
(如果加密,则为wss
),服务器网址就是 URL。
四、实例:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.pinnet</groupId> <artifactId>springboot-websocket</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>1.5.9.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>1.5.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> <version>1.5.9.RELEASE</version> </dependency> </dependencies> </project>
2)websocket配置
package com.pinnet.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; @Configuration public class WebSocketConfig { //加入配置,目的使用注解连接websocket @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
3)websocket的连接处理服务
package com.pinnet.controller; import org.springframework.stereotype.Component; import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @Component //websocket的连接名称 @ServerEndpoint(value = "/webSocket") public class WebSocketServer { private Session session; private List<WebSocketServer> webSocketServers = new CopyOnWriteArrayList<WebSocketServer>(); //打开连接时的操作 @OnOpen public void onOpen(Session session) { this.session = session; webSocketServers.add(this); } //关闭连接时的操作 @OnClose public void onClose() { webSocketServers.remove(this); } //接手消息时的操作 @OnMessage public void onMessage(String message) { for (WebSocketServer webSocketServer: webSocketServers) { try { sendMessage(webSocketServer, message); } catch (Exception e) { e.printStackTrace(); } } } //发送消息 public void sendMessage(WebSocketServer webSocketServer,String message) throws IOException { webSocketServer.session.getBasicRemote().sendText(message); } }
4)顺便谢了一个测试的js,可以直接在浏览器console里面执行测试
var websocket = null; if ('WebSocket' in window) { websocket = new WebSocket('ws://localhost/webSocket'); } else { alert('该浏览器不支持websocket'); } websocket.onopen = function (event) { console.log('websocket建立连接'); websocket.send("websocket发送消息"); } websocket.onclose = function (event) { console.log('websocket关闭连接'); } websocket.onmessage = function (event) { console.log('websocket收到消息:' + event.data); }
五、springboot的简单用法就是这样的,当然实际的用法,需要进行封装,具体的处理以及使用都要,一定的框架支持。
六、源码下载:https://pan.baidu.com/s/1cHF_UIFb2cMTcmDM4UlzlA