即时通讯的实现:短轮询、长轮询、SSE 和 WebSocket 间的区别
学习内容:
短轮询:短轮询是一种客户端与服务器之间的通讯方式,客户端定期向服务器发送请求,以检查是否有新消息。如果没有新消息,服务器会返回一个空响应。这种方法的缺点是客户端发送的请求频率较高,这可能导致网络拥塞和服务器负载过高。
长轮询:长轮询是一种改进的轮询方式,其中客户端发送一个请求并保持连接打开,直到服务器有新消息可用或连接超时。这种方法减少了不必要的请求,但仍然需要发送大量的 HTTP 请求。
SSE:SSE(Server-Sent Events)是一种单向通信协议,其中服务器可以将消息推送到客户端。与轮询不同,客户端只需发送一个请求,服务器可以随时发送新消息。这种方法可以减少网络流量和服务器负载。
WebSocket:WebSocket 是一种双向通信协议,它允许服务器和客户端在连接打开的情况下实时通信。WebSocket 可以减少网络流量和服务器负载,因为它不需要客户端发送大量的 HTTP 请求来获取新消息。
举例:
短轮询:某个社交媒体应用程序中的聊天功能使用短轮询来检查是否有新消息。
长轮询:在线游戏中,玩家使用长轮询来获取其他玩家的实时位置和动作。
SSE:新闻网站可以使用 SSE 将新闻标题和摘要推送到用户,而无需用户手动刷新页面。
WebSocket:在线会议软件使用 WebSocket 实现实时音频和视频通信,以及在会议期间共享文档和屏幕。
短轮询和长轮询是基于 HTTP 的轮询技术,SSE 是一种单向通信协议,WebSocket 是一种双向通信协议。WebSocket 相对于其他技术而言具有更好的性能和更低的延迟,因此成为即时通讯的首选技术。
WebSocket 使用方法:
1.创建 WebSocket 对象:可以在客户端使用 JavaScript 的 WebSocket API 创建 WebSocket 对象。例如,可以使用以下代码创建 WebSocket 对象并连接到服务器:
const socket = new WebSocket('ws://localhost:8080/my-websocket');
2.处理 WebSocket 事件:WebSocket 对象具有多个事件,可以使用这些事件来处理连接状态、接收和发送数据等。例如,可以使用以下代码监听 WebSocket 对象的打开事件:
下面展示一些 内联代码片
。
socket.addEventListener('open', (event) => {console.log('WebSocket 连接已打开');
});
3.发送和接收数据:可以使用 WebSocket 对象的 send() 方法向服务器发送数据,也可以使用 onmessage 事件来接收来自服务器的数据。例如,可以使用以下代码发送消息并处理来自服务器的响应:
socket.send('Hello, server!');socket.addEventListener('message', (event) => {console.log('服务器返回数据:', event.data);
});
4.关闭 WebSocket 连接:当不再需要 WebSocket 连接时,可以使用 WebSocket 对象的 close() 方法关闭连接。例如,可以使用以下代码关闭 WebSocket 连接:
socket.close();
需要注意的是,WebSocket 连接需要在服务器端也进行支持。服务器端需要实现 WebSocket 协议,并监听客户端的连接请求。另外,WebSocket 连接需要在安全的 HTTPS 连接下使用,或者在本地开发环境下使用 ws:// 协议。
WebSocket 后端 spring boot 怎么写
1.添加依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.创建 WebSocket 配置类
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(myWebSocketHandler(), "/my-websocket").setAllowedOrigins("*");}@Beanpublic WebSocketHandler myWebSocketHandler() {return new MyWebSocketHandler();}
}
在这个例子中,我们创建了一个 WebSocket 处理程序 MyWebSocketHandler,并将其注册到 “/my-websocket” 路径下。setAllowedOrigins(“*”) 允许任何来源的客户端连接到 WebSocket。
3.创建 WebSocket 处理程序
public class MyWebSocketHandler implements WebSocketHandler {private List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {sessions.add(session);}@Overridepublic void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {for (WebSocketSession s : sessions) {if (s.isOpen() && !s.getId().equals(session.getId())) {s.sendMessage(message);}}}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {sessions.remove(session);}
}
这个处理程序维护了一个 WebSocketSession 列表,用于存储所有连接到 WebSocket 的客户端。在每个新客户端连接到 WebSocket 时,afterConnectionEstablished() 方法将会被调用,在这里我们将新客户端的 WebSocketSession 添加到列表中。在客户端发送消息时,handleMessage() 方法将被调用,我们在这里将消息转发给所有其他客户端。当客户端断开连接时,afterConnectionClosed() 方法将被调用,我们在这里将断开连接的客户端从列表中移除。
4.测试 WebSocket
const socket = new WebSocket("ws://localhost:8080/my-websocket");
socket.onmessage = (event) => {console.log("收到消息:", event.data);
};
socket.send("Hello, world!");
在客户端发送消息时,MyWebSocketHandler 的 handleMessage() 方法将会被调用,将消息转发给所有其他客户端。