hugh 的个人博客

nodejs使用webSocket 和 web Notification实时通知用户

1. 项目框架

pm2 + express + vue

2. webSocket

node 端可以使用 express-ws包

npm install express-ws

 

3. app.js初始化ws

let ws = require('express-ws')
let app = express();

let expressWs = ws(app);

 

4. 定义ws 路由, 用于处理ws请求

app.ws('/ws', function(ws, req) {
    console.log(req.session)
    if(req.session && req.session.user_id) {
        wsClients.push({id: req.session.login.id, client: ws})
    }
    ws.on('message', function(msg) {
        console.log(msg);
    });
});

wsClients: 用于在当前实例中维持一个ws客户端集合

user_id: 标识用于登录session中的登录标识

6. 定义通知路径

exeNotifyWeb(users, info) {
         var clients = this.wsClients;
         console.log("个数"+clients.length)
         clients.forEach(function(item, index) {
             console.log("status:"+item.client.readyState)
             if(item.client && item.client.readyState === 1) { // 用于检测当前ws client 是否还处于连接打开状态
               isIn(item.client.id, users) && item.client.send(info)  // 如果当前用户是需要进行通知的, 则执行send方法
             } else {
                 clients.splice(index, 1) // 如果客户端已经关闭, 则移除出列表
             }
         })
     }

当需要执行通知时, 触发exeNotifyWeb方法。

 

7. 前端发送并接受消息

if ("WebSocket" in window)
{
    console.log("您的浏览器支持 WebSocket!");
// 打开一个 web socket
var ws = new WebSocket("ws://"+window.location.host+"/ws");

ws.onopen = function()
{
    // Web Socket 已连接上,使用 send() 方法发送数据
    ws.send("发送数据");
    setInterval(function() {
        ws.send("发送数据-healthcheck"); // 注意需要加上心跳处理, 防止长时间没有消息,导致链接断开
    }, 5000)
};

ws.onmessage = function (evt)
{
    var received_msg = evt.data;
    console.log("数据已接收..." + received_msg);
    notification.notify(received_msg)
};

ws.onclose = function()
{
    // 关闭 websocket
    console.log("连接已关闭...");
};

}

 

8. 存在问题

Q: 在pm2启动多个实例 或者使用集群部署时, 每个实例上分别维护了部分用户的ws链接, 导致消息通知时,可能无法通知到指定的用户

A:加外部redis,使用发布订阅模式, 每个客户端触发执行各自的exeNotifyWeb方法即可

 

 


标题:nodejs使用webSocket 和 web Notification实时通知用户
作者:hugh0524
地址:https://blog.uproject.cn/articles/2019/02/25/1551095101075.html