websocket给指定客户端推送消息

业务场景

最近有一个业务场景是要做实时语音转义,考虑到实时性,所以决定采用websocket实现。

业务场景是A客户端(手机)进行语音转义的结果实时同步到B客户端(pc),这就需要用到websocket将A转义的结果发送给服务端,服务端接收到A的信息直接同步推送给B,所以它就和简单的无差别广播不同了。

看了网上的websocket示例,很少关于如何针对指定客户端推送消息的,解释的也是错误的。于是决定写一个大家拿去即用的示例。

websocket的通信过程

首先解释下面示例websocket服务的通信过程

1.服务端起一个websocket的端口服务

2.然后客户端去 new WebSocket(服务端地址,如:ws://127.0.0.1:5201/?userId=liubao),此时就走到了服务端的wss.on(‘connection’)建立一个一对一连接了。为了方便大家理解,我把userId直接放url里了(真实业务场景一般是从header里拿token解析用户是谁)

3.服务端就把这个userId的请求连接池储存到clients数组里

4.此时客户端发送一个消息给服务端,就走到了 ws.on(‘message’)里,我们用data去接收客户端发送的消息

备注:从客户端接收到的数据是二进制的buffer信息(二进制信息是传统json信息速度的10倍+),所以在打印data时是个buffer,要想打印出来它的具体信息可以这样

console.log('%s',data);

取data信息时必须先转成字符串,否则是buffer数组信息,无法处理。

我们从客户端发送一个json信息包含userId和要发送的message

example:

// 客户端A
{ "userId": "liubao", "message": "给liubao一个小爱心" }
// 客户端B
{ "userId": "bob", "message": "给你bob一个大铁锤" }

5.有userId时遍历连接池,找到相同的userId连接池,进行推送消息

最后效果

在这里插入图片描述

服务端代码

copy下面代码到index.js文件,然后安装依赖和运行

npm i ws
node index.js
import { WebSocketServer } from 'ws';

const clients = []; // 与客户端建立的连接池

const wss = new WebSocketServer({ port: 5201 }); // 创建一个websocket服务
wss.on('connection', function connection(ws, request, client) {
  let url = request.headers.origin + request.url; // example:ws://127.0.0.1:5201/?userId=liubao
  let userId = getParam(url, 'userId');
  if (userId) {
    clients.push({ userId, ws: ws }); // 连接时只要url带userId参数,直接往客户端数组里塞入连接池信息
  }
  ws.on('message', function message(data, isBinary) { // 得到客户端往服务端发送的消息
    try {
      let objMessage = JSON.parse(`${data}`); // example:{ 'userId': 'liubao', 'message': '给你一个小爱心' }
      let { userId, message } = objMessage;
      let count = 0; // 发送客户端数量
      if (userId) {
        clients.forEach(e => {
          if (e['userId'] === userId) {
            count++;
            e['ws'].send(`${message}`);
          }
        });
        ws.send(`已发送userId为${userId}${count}个客户端`);
      } else {
        ws.send(JSON.stringify({ error: '请发送指定userId的客户端' }));
      }
    } catch (err) {
      ws.send(JSON.stringify({ error: err.message }));
    }
  });
  ws.on('close', function close(event) {
    console.log('关闭了');
  });
});

const getParam = (url, param) => new URLSearchParams(new URL(url).search).get(param); // es6获取URL参数方法
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

锅巴胸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值