赞
踩
WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocked API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
背景:很多网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的事件间隔,由浏览器发出HTTP请求,然后由服务器返回最新的数据给客户端浏览器。这种传统的模式有很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
而比较新的技术去做轮询的效果是Comet。这种技术虽然可以双向通信,但仍然需要反复发出请求,而且在Comet中普遍采用的长链接,也会消耗服务器资源。
这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够实时的进行通信。
Http请求头添加属性
Connection: Upgrade // 客户端希望连接升级
Upgrade: websocket // 升级到Websocket协议
<body> 输入:<br/><input id="text" type="text"/> <button onclick="send()">发送消息</button> <hr/> <button onclick="closeWebSocket()">关闭连接</button> <hr/> </body> <script type="text/javascript"> var websocket = null; // 判断当前浏览器是否支持WebSocket if ('WebSocket' in window) { websocket = new WebSocket("ws://localhost:9082/ws/123"); } else { alert('Not support Websocket') } // 发生错误的回调方法 websocket.onerror = function () { alert("WebSocket连接发生错误"); }; // 成功建立的回调方法 websocket.onopen = function () { alert("WebSocket连接成功"); } // 接收到消息的回调方法 websocket.onmessage = function (event) { alert(event.data); } // 连接关闭的回调方法 websocket.onclose = function () { alert("WebSocket连接关闭"); } // 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常 window.onbeforeunload = function () { websocket.close(); } // 发送消息 function send() { var message = document.getElementById('text').value; websocket.send(message); } </script>
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
后端
@Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } } @Component @ServerEndpoint("/ws/{name}") public class WebSocketTest { Logger log = LoggerFactory.getLogger(this.getClass()); private static Map<String, WebSocketTest> webSocketSet = new ConcurrentHashMap<>(); private Session session; private String name; @OnOpen public void onOpen(Session session, @PathParam("name") String name) { this.session = session; this.name = (name == null || name.length() == 0) ? UUID.randomUUID().toString() : name; // 将新连接放入Set webSocketSet.put(name, this); log.info("WebSocket有新的客户端连接:{}, 当前连接数为:{}", name, webSocketSet.size()); } @OnClose public synchronized void onClose() { // 清除当前连接 webSocketSet.remove(name); log.info("WebSocket:{}已关闭, 当前连接数为:{}", name, webSocketSet.size()); } @OnMessage public void onMessage(String message) { log.info("接收到webSocket消息client:{}, message:{}", name, message); try { webSocketSet.get(name).session.getBasicRemote().sendText(message); } catch (IOException e) { log.error("WebSocket发送消息失败!from{}, to{}, error{}", this.name, name, e.getMessage()); } // 群发 webSocketSet.forEach((name, ws) -> { try { ws.session.getBasicRemote().sendText(message); } catch (IOException e) { log.error("WebSocket群发送消息失败!from{}, to{}, error{}", this.name, name, e.getMessage()); } }); log.info("WebSocket群发送消息, from:{}", this.name); } }
Socket 是传输控制层协议,WebSocket 是应用层协议。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。