WebSocket是一种实现全双工通信的网络技术标准,它允许在用户的浏览器和服务器之间进行持久的、双向的通信。以下是对WebSocket的具体介绍:
- 实时性:与传统HTTP请求相比,WebSocket提供了更高效的实时数据交换方式。一旦建立连接,客户端与服务端可以同时相互发送信息,而不需要像HTTP那样每次请求都要重新建立连接。
- 持久连接:WebSocket建立在TCP协议之上,它使用一次“握手”来建立连接,此后便可以在客户端和服务器之间保持一个持久的连接状态,直到其中一方主动关闭连接。
- 低延迟:由于WebSocket支持长连接和双向通信,它可以显著减少网络延迟,尤其适用于需要快速响应的场景,例如在线游戏、实时通知等。
- 轻量级:虽然WebSocket基于HTTP协议,但它有自己的专门协议,这使得它在传输效率上更高,头部信息更小,减少了额外的数据传输开销。
- 兼容性:WebSocket协议得到了现代浏览器的广泛支持,并且由W3C定为标准。同时,它也通过RFC 6455和RFC 7936被IETF确定为标准。
- 适用场景:WebSocket特别适用于那些需要服务器主动向客户端推送数据的应用场景,如聊天室、实时监控图表更新展示等。
首先创建客户端WebSocket:
WebSocketClient.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>WS_Client</title>
</head>
<body>
<input id="msg" type="text">
<button onclick="send()">发送消息</button>
</body>
<script>//连接WebSocket 服务器const clientId = Math.random().toString(36).substr(2);const websocket = new WebSocket("ws://localhost:8080/ws/" + clientId);//监听连接建立成功websocket.onopen = function (){console.log("WebSocket建立连接成功……")}//监听收到服务端消息websocket.onmessage = function (event){console.log(event.data);}//发送消息function send(){websocket.send(document.getElementById('msg').value);}//监听窗口关闭事件,当窗口关闭时主动去关闭webSocket连接window.onbeforeunload = function (){websocket.close();}
</script>
</html>
现在编写服务端WebSocketServe:
引入相关依赖:
<!-- websocket --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>
编写WebSocketServer服务端:
package net.wanho.webSocket;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.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;@Component
@ServerEndpoint("/ws/{cid}")
public class WebSocketServer {//存放会话对象private static Map<String, Session> sessionMap = new HashMap<>();/*** 监听连接建立成功*/@OnOpenpublic void onOpen(Session session, @PathParam("cid") String cid){System.out.println("客户端:" + cid + "建立连接……");sessionMap.put(cid,session);}/*** 监听收到客户端消息*/@OnMessagepublic void onMessage(String msg,@PathParam("cid") String cid){System.out.println("这是来自于客户端:" + cid + "的消息:" + msg);}/*** 监听连接关闭* @param cid*/@OnClosepublic void onClose(@PathParam("cid") String cid){System.out.println("连接断开:" + cid);sessionMap.remove(cid);}/*** 群发消息*/public void sendToAllClient(String msg){Collection<Session> sessions = sessionMap.values();for (Session session : sessions) {try {//服务器向客户端发送消息session.getBasicRemote().sendText(msg);} catch (IOException e) {e.printStackTrace();}}}
}
编写WebSocket配置类:
/*** WebSocket配置类,用于注册WebSocket服务端组件*/
@Configuration
public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter(){return new ServerEndpointExporter();}
}
编写定时任务,用于向客户端发送信息:
@Component
public class MyWebSocketTask {@Resourceprivate WebSocketServer webSocketServer;/*** 通过WebSocket每隔5s向客户端发送信息*/@Scheduled(cron = "0/3 * * * * ?")public void sendMessageToClient(){String format = DateTimeFormatter.ofPattern("HH:mm:ss").format(LocalDateTime.now());webSocketServer.sendToAllClient("这是来自服务端的消息:" + format);}
}
在启动类开启定时任务:
@SpringBootApplication
@EnableScheduling //开启定时任务
public class ExcelProjectApplication {public static void main(String[] args) {SpringApplication.run(ExcelProjectApplication.class, args);}}
测试结果: