=最近在学习的过程中认识到了websocket!对于实现全双工通信,具有很大的帮助,所以,刚好疫情在家无聊,就想着能不能利用socket.io实现一下聊天室,以及私聊的功能!
###也算聊以慰藉在家真的无聊,我只能自己和自己聊天的假象了
这里呢我以express+socket.io来实现功能
###初始化项目,下载相对应的依赖
npm init -y
npm install express --save
npm install socket.io --save
###先撰写服务端的代码实现
const express = require('express')
const app = express()
const http = require('http').createServer(app)
const io = require('socket.io')(http);
io.on('connection',(socket)=>{
console.log('有用户连接了')
### 这里的socket是单独且唯一的###
socket.on('xxx发送事件名',(msg要返回给客户端的内容)=>{
###单独返回
socket.emit('xxx接受事件名',msg)
###广播返回(也就是大家都能收到)
socket.boradcast.emit('xxx接受事件名',msg)
})})
###先介绍一下有关于socket.io如何初始化传参
服务端接受是传过来的值:
socket.handshake.query.xxx
客户端发送的方式为:
const socket = io('localhost:3000',{
query:{ key:value }
})
当然io()函数里面的第二参数里面有多种传参方式,大家可以去看官方API去参考,我这里是介绍比较常用的传参方式
###初始化存入每个用户的socket(这个很关键)
var socket_list = []
io.on('connection',(socket)=>{
console.log('用户连接了')
let nickname = socket.handshake.query.nickname
socket_list.push({
user:nickname,
'socket':socket
})
###公共聊天室和私聊的区别在哪
公共聊天室
只需要在客户端发起连接以后,发送广播通知就能实现,也就是借助socket.boradcast.emit('xxx接受事件名',msg)
私聊功能
这个就需要得到你私聊对象的socket,前面提到了,每个人的socket是独一无二的,所以在一开始,你就可以把所有连接服务器的用户的socket都保存在一个集合中
然后根据你传过来的标识符,进行查找
socket.on('only',(data)=>{//私聊返回的对象
const {user,msg} = data
这里面我就是在一开始的初始化连接中,我要求用户登陆才可以连接服务端,所以user就是作为他们的标识符,然后通过标识符查到对应的socket,然后发送消息
let client = socket_list.find(item=>item.user == user)
console.log(client)
if(client){
client.socket.emit('onlyyou',{
who:nickname,
user,
msg})
}})
###在我写的过程中踩到的坑
就是在我存入每个用户的socket时,我只能在初始化的时候存入,如果在socket.on()事件中存入时,服务端就会报内存过载的问题,后来我查了很多大神的笔记,只知道,如果在socket.on()中存入时,socket.io就会默认为递归引用,才会造成内存溢出的问题!所以这个坑折磨了我好久,在这里分享一下,希望大家不会踩到
###最后分享一下我小项目的成果
###总体效果就实现了,但是还有一些前端方面的小瑕疵,我个人还在完善...
慢慢努力,未来可期!!!加油自己