从零开始用react + tailwindcss + express + mongodb实现一个聊天程序(十一) 实现服务端和客户端socketio 连接
1.后端部分
socketIO文档参考Socket.IO
首先在lib下新建socket.js文件
参考服务器API | Socket.IO
import {Server} from 'socket.io';
import http from 'http'
import express from "express"
const app = express()
const server = http.createServer(app)
const io = new Server(server, {
cors: {
origin: "http://localhost:5173",
}
})
// 获取信息接收人的socketId
export function getReceiverSocketId(userId) {
return userSocketMap[userId]
}
// 当前连接的用户socketMap 统计在线用户
const userSocketMap = {}; // {userId:socketId}
// 监听用户连接
io.on("connection", (socket) => {
console.log("用户连接",socket.id)
// 用户连接时传过来的userId
const userId = socket.handshake.query.userId
// 如果userId存在,则添加到userSocketMap
if(userId) userSocketMap[userId] = socket.id
// 当前在线用户广播
io.emit("getOnlineUsers", Object.keys(userSocketMap))
socket.on("disconnect", () => {
console.log("用户失去连接",socket.id)
// 从userSocketMap中移除
delete userSocketMap[userId]
// 当前在线用户广播
io.emit("getOnlineUsers", Object.keys(userSocketMap))
})
})
export {io, app, server}
这时修改下index.js 的引入
import {app,server} from './lib/socket.js'
2.前端部分
useAuthStore.js 引入io
import {io} from "socket.io-client"
新增2个state属性 onlineUsers: [], // 在线用户 socket:null //socket 当前用户连接实例
常量定义 const BASE_URL = "http://localhost:3000"
我们创建2个方法
connectSocket: () => {
const {authUser} = get()
// 如果已经登录,并且socket已经连接,则不重新连接
if(!authUser || get().socket?.connected) return
const socket = io(BASE_URL, {
// 指定query参数 把自己userId传给socket
query: {
userId: authUser._id
}
})
socket.connect()
// 设置socket实例 如不设置 disconnectSocket失效
set({socket})
// 监听服务端推送过来的在线用户列表
socket.on("getOnlineUsers", (userIds) => {
set({onlineUsers: userIds})
})
},
disconnectSocket: () => {
if(get().socket?.connected) {
get().socket.disconnect()
}
}
在login方法中 我们登录成功后 要调用connectSocket方法
在logout方法中加入
get().disconnectSocket()
3.测试
前端用户登录成功后 后端打印xx用户已连接
用户退出登录时 后端打印 用户失去连接
下篇 继续 socketio处理消息的转发 广播