场景
当发生了用户被点赞、评论、关注等操作时,需要由服务器向用户实时地推送一条消息。
实现方式
后台Node.js
后端推送消息的处理流程
在 Node 服务器建立一个用户信息和 socket id 的映射表,因为同一用户可能打开了多个页面,所以他的 socket id 可能存在多个值。当用户建立连接时,往其中添加值;用户断开连接后,删除相应值。
当 Java 后台存在需要推送的消息时,会向 Node 服务器的 /api 路径 post 一条消息,其中包括用于标识用户的 tokenId 和其它数据。
Node 服务器接收到 post 请求后,对请求内容进行处理。根据 tokenId 找出与该用户对应的 socket id,socket.io 会根据 id 来向用户推送消息。
对用户信息的处理
方便起见,这里只用一个数组保存用户信息,实际工作中可以根据需要放入数据库中保存。
1 | global.users = []; // 记录下登录用户的tokenId, socketId |
当用户登录时,client 会向 server 发送 user_login 事件,服务器接收到后会做如下操作:
1 | socket.on('user_login', function(info) { |
addSocketId() 会向 users 数组中添加用户信息,不同用户通过 tokenId 进行区分,每个用户有一个 socketIds 数组,保存可能存在的多个 socketId。该函数的具体代码可见 src/utils.js 文件。
同理,还有一个 deleteSocketId() 函数用于删除用户信息,代码可见同一文件。
在获取了用户的 tokenId 之后,就需要找到对应的 socketId,然后向特定用户推送消息。
1 | // 只向 id = socketId 的这一连接发送消息 |
服务器的思路大致如此,接下来介绍客户端中是如何进行相应的处理的。
客户端
Socket.io 的初始化
首先在 html 文件中引入 Socket.io 的 client 端文件,例如通过 CDN 引入:
1 | <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script> |
其它的引入方式:
1 | const io = require('socket.io-client'); |
引入 Socket.io 后就获得了 io 函数,通过它来与消息推送服务器建立连接。
1 | // 假设你将 Node 服务器部署后的地址为:https://www.example.com/ws |
如果监听本地:
1 | const msgSocket = io('http://localhost:4001'); |
这里如果写成 io(‘https://www.example.com/ws') 会出现错误,需要将 /ws 写入path中。
为了能在其它文件使用这一变量,可将 msgSocket 作为一个全局变量:
1 | window.msgSocket = msgSocket; |
用户建立连接
// 用户登录时,向服务器发送用户的信息。服务器会在收到信息后建立 socket 与用户的映射。
msgSocket.emit(‘user_login’, {
userId,
socketId: msgSocket.id,
tokenId
});
##demo
[demo博文原文](https://segmentfault.com/a/1190000010974426)
[demo](https://github.com/noiron/socket-message-push)
##资料
[socket-io官网](https://socket.io/get-started/chat/)