从零开始用react + tailwindcss + express + mongodb实现一个聊天程序(十一) 实现服务端和客户端socketio 连接

发布于:2025-03-05 ⋅ 阅读:(63) ⋅ 点赞:(0)

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处理消息的转发 广播 


网站公告

今日签到

点亮在社区的每一天
去签到