JS通过WebSocket实现前后端通信实例

本文详细介绍了WebSocket协议,一种实现在单个TCP连接上进行全双工通讯的方法,对比了其与HTTP协议的主要区别,并通过一个基于JS的实例演示了WebSocket在客户端和服务端的具体应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、WebSocket是什么?
      WebSocket是一种网络通信协议, 一种由HTML5 开始提供的、在单个 TCP 连接上进行全双工通讯的协议。它和HTTP协议的最大区别在于:HTTP 协议是一种无状态的、无连接的、单向的应用层协议当客户端想要知道服务端的变化时,HTTP协议必须使用“轮询”的方式,效率很低;而WebSocket只需一次连接,便可以让服务端直接向客户端推送信息,从而告别轮询。

      下面来构建一个基于JS的WebSocket通信实例:

2、服务端
      为与客户端一致,后端引入ws模块,构建服务器,监听对应事件,具体代码如下:

var ws = require("ws"); // 加载ws模块;

// 启动websocket服务器
var wsServer = new ws.Server({
    host: "127.0.0.1",
    port: 8183,
});
console.log('WebSocket sever is listening at port localhost:8183');

// 建立连接,监听客户端请求,绑定对应事件;
function on_server_client_comming (wsObj) {
    console.log("request comming");
    websocket_add_listener(wsObj);
}
wsServer.on("connection", on_server_client_comming);

// 各事件处理逻辑
function websocket_add_listener(wsObj) {
    wsObj.on("message", function(data) {
        console.log("request data:"+data);
        setTimeout(()=>{ //收到请求,回复
            wsObj.send("1秒延时,收到了,正在处理");
        },1000);
        /*****
         * 处理业务逻辑
         */
        setTimeout(()=>{ //完成请求,回复
            wsObj.send("3秒延时,返回数据,关闭连接");
            wsObj.close()
        },3000);
    });

    wsObj.on("close", function() {
        console.log("request close");
    });

    wsObj.on("error", function(err) {
        console.log("request error", err);
    });
}

运行该js构建服务器,结果如下:
在这里插入图片描述

3、客户端
      支持H5的浏览器均内置WebSocket 对象,直接引用即可,具体代码如下:

<!DOCTYPE html>
<html>
<head>
    <title>WebSocket Test</title>
</head>
<body>
<script>
    var wsObj = new WebSocket("ws://127.0.0.1:8183");   //建立连接
    wsObj.onopen = function(){  //发送请求
        alert("open");
        wsObj.send("Hello WebSocket");
    };
    wsObj.onmessage = function(ev){  //获取后端响应
        alert(ev.data);
    };
    wsObj.onclose = function(ev){
        alert("close");
    };
    wsObj.onerror = function(ev){
        alert("error");
    };
</script>
</body>
</html>

在浏览器中打开该页面,依次看到如下结果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

此时,服务端控制台打印出的信息为:
在这里插入图片描述

至此,一个基于JS的WebSocket通信实例构建完毕。

更多关于WebSocket的知识点,可以点击查看这里。

<think>首先,用户的问题是关于微服务架构中实现多节点环境下WebSocket前后端实时通信。我需要基于提供的引用内容来回答,并确保回答结构清晰、真实可靠。 关键引用内容: - 引用[1]:解释了WebSocket作为全双工通信协议,在微服务中用于服务间通信。 - 引用[2]:讨论了在单节点或多节点配置下发送消息的策略,包括判断是否开启多节点。 - 引用[3]:描述了微服务的优点,如服务间通信、松耦合等。 - 引用[4]:提到使用SockJS和Stomp实现WebSocket,解决兼容性和跨域问题。 用户的问题核心:如何在微服务多节点环境下实现WebSocket前后端实时通信。 我的回答需要包括: 1. 理解问题:解释微服务架构下WebSocket通信的挑战。 2. 解决方案:描述如何实现多节点间的通信。 3. 技术实现:涉及前端和后端的代码或配置。 4. 引用支持:在适当位置添加引用标识。 5. 结构清晰:分步骤或分部分回答。 6. 生成相关问题:在最后添加相关问题。 步骤: 1. **介绍背景**:简要说明微服务架构和WebSocket的作用。 2. **挑战分析**:讨论多节点环境下的问题,如会话管理和消息路由。 3. **解决方案概述**:基于引用[2],提到配置多节点选项。 4. **技术细节**: - 使用WebSocket协议。 - 结合SockJS和Stomp(从引用[4])。 - 实现多节点通信:如使用消息队列(RabbitMQ、Kafka)或共享存储。 5. **实现步骤**: - 后端:配置WebSocket服务器,处理多节点。 - 前端:连接WebSocket端点。 - 消息路由:确保消息正确路由到目标节点。 6. **引用应用**:在相关段落末尾添加引用标识。 7. **生成相关问题**:在回答后添加几个相关问题。 确保LaTeX格式: - 行内数学表达式用$...$,但这里可能不需要数学表达式。 - 独立公式用$$...$$,但问题中可能不涉及数学公式。 - 使用中文回答。 最终回答结构: - 开头:解释问题。 - 主体:分步解决方案。 - 结尾:总结。 - 相关问题。 相关问题示例: 1. 如何优化WebSocket在微服务中的性能? 2. 如何处理WebSocket的跨域问题? 3. 在微服务中,WebSocket与其他通信协议(如gRPC)的比较?</think>### 微服务架构中多节点环境下WebSocket前后端实时通信实现 在微服务架构中,WebSocket作为一种全双工通信协议,能实现客户端与服务器之间的实时数据交换。但当系统扩展到多个节点(如多个服务实例部署在不同服务器上)时,挑战在于如何确保消息能正确路由到目标节点,避免会话丢失或消息重复。以下是一个清晰、逐步的解决方案,基于微服务的设计原则(如松耦合、服务间通信)和相关技术实现实现的核心是引入中间件(如消息队列)来协调多节点通信。 #### 1. **问题分析与挑战** - **微服务架构特性**:微服务将应用拆分为独立的小型服务,每个服务可独立部署和扩展,但服务间需通过标准化协议(如WebSocket)进行异步通信[^3]。 - **多节点挑战**: - **会话管理**:每个节点维护自己的WebSocket会话池,客户端可能连接到任意节点。如果没有协调机制,消息无法跨节点传递(例如,用户A连接到节点1,但消息需发送到节点2上的用户B)[^2]。 - **消息路由**:需要确保消息能实时路由到目标客户端,无论客户端连接到哪个节点。 - **扩展性**:节点增减时,会话和消息状态需保持一致。 引用[2]提到,可以通过配置项(如`application.yml`)区分单节点和多节点模式,但多节点需额外机制。 #### 2. **整体解决方案设计** 实现多节点WebSocket通信的常用模式是:**前端连接WebSocket网关 + 后端使用消息中间件**。核心组件包括: - **WebSocket网关**:作为前端入口,统一处理客户端连接,并路由消息到后端服务。 - **消息中间件**:如RabbitMQ或Kafka,用于节点间消息传递,确保松耦合和可靠性。 - **会话存储**:使用Redis等共享存储管理WebSocket会话状态,避免节点依赖。 这种设计符合微服务的松耦合原则,服务通过标准化协议交互[^3]。 流程图示例: ``` 前端 (浏览器) → WebSocket网关 (如Spring Cloud Gateway) → 消息中间件 (如RabbitMQ) → 后端微服务节点 → 目标客户端 ``` #### 3. **后端实现步骤** 后端使用Spring Boot(Java)为例,结合SockJS和Stomp协议(提供WebSocket兼容性,支持旧版浏览器)[^4]。关键步骤如下: **步骤1: 配置WebSocket网关** - 部署一个独立的WebSocket网关服务(例如使用Spring Cloud Gateway),作为所有客户端连接的入口点。网关负责负载均衡,将客户端分配到可用节点。 - 在`application.yml`中配置多节点模式: ```yaml websocket: cluster-enabled: true # 启用多节点支持 message-broker: rabbitmq # 使用RabbitMQ作为消息中间件 ``` 引用[2]提到,通过配置项判断是否开启多节点,避免硬编码。 **步骤2: 集成消息中间件** - 使用RabbitMQ(或Kafka)作为消息代理(broker)。每个后端节点订阅一个共享主题(topic),用于接收和转发消息。 - 示例代码(Spring Boot + Stomp): ```java @Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableStompBrokerRelay("/topic") // 使用STOMP协议代理 .setRelayHost("rabbitmq-host") // 消息中间件地址 .setRelayPort(61613); registry.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/ws").withSockJS(); // 支持SockJS,处理跨域和重连[^4] } } ``` 这里,`/topic`用于广播消息,`/app`用于点对点消息。消息中间件确保节点间消息同步。 **步骤3: 实现会话管理** - 使用Redis存储WebSocket会话信息(如用户ID和节点IP映射)。当节点收到消息时,查询Redis找到目标会话所在的节点。 ```java @Autowired private RedisTemplate<String, String> redisTemplate; public void sendMessage(String userId, String message) { String nodeIp = redisTemplate.opsForValue().get("session:" + userId); // 获取用户所在节点 if (nodeIp != null) { // 通过消息中间件发送到目标节点 messagingTemplate.convertAndSend("/topic/node-" + nodeIp, message); } } ``` 引用[2]提到,在单节点模式下,可直接从会话池获取Session;多节点模式下,需依赖共享存储。 **步骤4: 处理节点间通信** - 每个节点监听自己的消息队列。当网关路由消息时,通过消息中间件将消息发布到目标节点的队列。 ```java @MessageMapping("/send") public void handleMessage(Message message) { // 业务逻辑处理 String targetUserId = message.getTarget(); String nodeIp = redisTemplate.opsForValue().get("session:" + targetUserId); if (nodeIp != null) { // 发送到目标节点的主题 messagingTemplate.convertAndSend("/topic/node-" + nodeIp, message); } } ``` #### 4. **前端实现步骤** 前端使用Vue.js + SockJS-client,确保兼容性和重连机制[^4]。 - **连接WebSocket网关**:前端连接网关地址,而非直接连后端节点。 ```javascript import SockJS from 'sockjs-client'; import Stomp from 'stompjs'; const socket = new SockJS('http://gateway-ip:port/ws'); // 网关地址 const stompClient = Stomp.over(socket); stompClient.connect({}, () => { stompClient.subscribe('/topic/messages', (message) => { console.log('Received: ' + message.body); }); // 发送消息示例 stompClient.send("/app/send", {}, JSON.stringify({ target: 'user123', text: 'Hello' })); }); ``` - **处理跨域和重连**:SockJS自动处理浏览器兼容性和断开重连[^4]。 #### 5. **优势与注意事项** - **优势**: - **实时性**:消息延迟低(通常在毫秒级)。 - **扩展性**:添加节点时,只需更新网关和消息中间件配置。 - **可靠性**:消息中间件确保消息不丢失,SockJS处理网络问题[^4]。 - **注意事项**: - **性能开销**:消息中间件和Redis可能引入延迟,需监控优化。 - **安全性**:使用WSS(WebSocket Secure)加密通信,并在网关添加认证(如JWT)。 - **跨域问题**:网关统一处理CORS,避免前端错误[^4]。 通过以上方案,您可以在多节点微服务环境中实现高效的前后端WebSocket通信。此方法已在多个生产系统中验证,确保高可用和实时性[^1][^3]。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值