注册账号登录
月下
我的小站www.xiaosuibi.com
关注

socket 一对一私聊的实现方式是啥

技术NodeJS创建于2020/02/14599次阅读1人收藏
看了很多文章,都不一样,有点想不通
4条评论 / 5条回复
 不知道其他人是怎么实现的,分享一下自己的实现方法,供你参考。

客户端,启动监听事件,事件名称为用户的id。
socket.on('user_id', callback);

客户端、服务端,都可以给指定user_id发送广播。
socket.emit('user_ud', params, callback);

大概就是这样。
回复
补充一下~

和 @月下 私信讨论私信功能的时候,告知我,我的私信是以广播形式发送的,这是不正确的方式,因为针对某个用户的私信消息,使用广播形式的话,对于不需要接收消息的用户,是一种带宽资源的浪费。

因此自己又研究了一下,想到2种实现的方式。

1、使用列队数组的方式
当登陆的用户,客户端连接上服务端socket的时候,做一个数组列队[{ userId, socketId }, ...],记录用户id、socketId,方便通过用户的id找到该用户的socketId,然后用这个socket发送消息,socket断开的时候,再从数组列队中移除。

2、房间聊天的方式
当登陆的用户,客户端连接上服务端socket的时候,加入到一个以用户id命名的房间,发送私信的时候发送到这个房间,socket断开的时候,同时离开这个房间。

自己感觉2的方式简单一些,不用自己维护一个数组列队,因为考虑一个账号可能多平台登陆,也需要小广播消息,所以暂时先用这个方式实现了。

加入房间
socket.join(userId, ()=>{});
https://socket.io/docs/server-api/#socket-join-room-callback

给房间发送事件消息
io.sockets.to(userId).emit('an event', { some: 'data' });
https://socket.io/docs/server-api/#socket-to-room

socket断开连接的时候,离开用户的房间
socket.leave(userId, ()=>{})
https://socket.io/docs/server-api/#socket-leave-room-callback
2020/02/171 人赞
回复
继续补充~
@月下,发现的另一种方法,
将用户名直接设置为socket的name属性,通过name属性来找到socket,并发送消息
https://blog.csdn.net/koastal/article/details/53677766
2020/02/18
回复
还是有点没懂 ...
回复
客户端一连接socket ,就用自己的用户id  socket.on('user_id', callback);?
回复
是的,这样是全局的做法。
2020/02/14
回复
但是我发现,好像信息会暴露在控制台
2020/02/17
回复
如果是登陆用户自己的话,感觉可以忽略吧。
如果要严格信息安全性,可以只接收私信消息的id,接收到再通过api去获取具体的私信内容,当然api需要带上用户的token,做身份的判断。
2020/02/17
回复
别折腾了,即时通讯不是人干的事,我砸了近十万了,没得用,最后还是走三方接网易云API,做个人websocket足以,做企业的趁早别费劲了,项目太大了,吃不动的,不管是自己从头写还是接手别人的项目,哪怕是全套的都搜不了的,bug太多了
回复
月下
我的小站www.xiaosuibi.com
关注私信
1
关注
4
粉丝
10
帖子