当前位置: 首页 > news >正文

从零开始用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处理消息的转发 广播 

相关文章:

  • Loki+Promtail+Grafana监控K8s日志
  • ubuntu20.04 安装离线版docker-20.10.0
  • C语言_数据结构总结2:动态分配方式的顺序表
  • MariaDB Galera 原理及用例说明
  • 图像清晰度评价函数设计
  • CobaltStrike Beacon上线包解析
  • 本地jar包添加到 maven
  • 前端基础之消息订阅与发布
  • 黑马点评2 商户查询缓存
  • 十、Redis 主从复制:原理解析、配置实践与优化策略
  • PCA(主成分分析)核心原理
  • [QT]开发全解析:从概念到实战
  • 【渗透测试】反弹 Shell 技术详解(一)
  • 苍雾世界新手玩法介绍 苍雾世界什么角色比较强
  • 从开源大模型工具Ollama存在安全隐患思考企业级大模型应用如何严守安全红线
  • SQL刷题:自连接(Self-Join)--通过将 同一张表连接两次,比较不同行之间的数据关系
  • 在Ubuntu上搭建Samba服务,实现与windows之间的文件共享
  • 如何评价字节发布的集成了AI的IDE trae?和cursor相比,有什么优势和劣势?
  • kan pinn
  • ArcGIS Pro建库中常用公式的应用与技巧
  • 气急败坏!20多名台湾艺人被台当局列为“重点核查对象”
  • 武康大楼再开发:一栋楼火还不够,要带火街区“朋友圈”
  • 李伟任山东省委常委、省纪委书记
  • 六省会共建交通枢纽集群,中部离经济“第五极”有多远?
  • 关税互降后的外贸企业:之前暂停的订单加紧发货,后续订单考验沟通谈判能力
  • 总奖金池百万!澎湃与七猫非虚构写作与现实题材征文大赛征稿启动