学习 Socket.IO 实现实时数据共享:聊天应用程序示例

Socket.IO 是一个功能强大的库,用于在 Web 客户端和服务器之间进行实时双向通信。它通常用于构建聊天应用、游戏平台和协作工具等应用程序。本文将介绍如何使用 Socket.IO 创建 MERN 堆栈聊天应用程序,涵盖所有关键步骤。

前提条件

确保已安装以下软件:

  • Node.js
  • npm
  • MongoDB(如果需要后端数据库)

1. 设置项目

为你的项目创建一个新文件夹并初始化一个 Node.js 项目:

mkdir meern-socketio-chat 
cd meern-socketio-chat 
npm init -y

安装所需的依赖项:

npm install express socket.io mongoose cors

2. 后端实现

创建 Express 服务器并集成 Socket.IO

现在将创建一个 Express 服务器并集成 Socket.IO 逻辑。

index.js

import express from "express";
import http from "http";
import mongoose from "mongoose";
import { Server } from "socket.io";
const app = express();
const server = http.createServer(app);
const PORT = 5000;
// MongoDB 连接函数
async function connectDB() {
    try {
        await mongoose.connect("mongodb://localhost:27017/chat", {
            useNewUrlParser: true,
            useUnifiedTopology: true,
        });
        console.log("MongoDB connected");
    } catch (err) {
        console.error("MongoDB connection failed", err);
        process.exit(1);
    }
}
const io = new Server(server, {
    cors: {
        origin: ["http://localhost:5173"],
    },
});
const userSocketMap = {};
export function getReceiverSocketId(userId) {
    return userSocketMap[userId];
}
io.on("connection", (socket) => {
    console.log("A user connected", socket.id);
    const userId = socket.handshake.query.userId;
    if (userId) userSocketMap[userId] = socket.id;
    io.emit("getOnlineUsers", Object.keys(userSocketMap));
    socket.on("disconnect", () => {
        console.log("A user disconnected", socket.id);
        delete userSocketMap[userId];
        io.emit("getOnlineUsers", Object.keys(userSocketMap));
    });
});
server.listen(PORT, () => {
    console.log("Server is running on port:", PORT);
    connectDB();
});
export { io, app, server };

发送目标消息

在服务器逻辑中,您可以向特定用户发送消息:

constreceiverSocketId = getReceiverSocketId (receiverId); 
if (receiverSocketId) { io.to
     ( receiverSocketId) .emit ( "newMessage" , newMessage); }

3. 前端实现

将客户端连接到 Socket.IO

使用 React 客户端连接到 Socket.IO 服务器。

套接字连接逻辑(socket.js

import { io } from "socket.io-client";
import create from "zustand";
const BASE_URL = "http://localhost:5000";
const useSocketStore = create((set, get) => ({
    socket: null,
    onlineUsers: [],
    connectSocket: () => {
        const { authUser } = get();
        if (!authUser || get().socket?.connected) return;
        const socket = io(BASE_URL, {
            query: {
                userId: authUser._id,
            },
        });
        socket.connect();
        set({ socket: socket });
        socket.on("getOnlineUsers", (userIds) => {
            set({ onlineUsers: userIds });
        });
    },
    disconnectSocket: () => {
        if (get().socket?.connected) get().socket.disconnect();
    },
}));
export default useSocketStore;

4. 构建聊天 UI

React 组件示例

Chat.js

import React, { useEffect, useState } from "react";
import useSocketStore from "./socket";
const Chat = () => {
    const [message, setMessage] = useState("");
    const [messages, setMessages] = useState([]);
    const { socket, connectSocket, disconnectSocket, onlineUsers } = useSocketStore();
    useEffect(() => {
        connectSocket();
        socket?.on("newMessage", (newMessage) => {
            setMessages((prevMessages) => [...prevMessages, newMessage]);
        });
        return () => {
            disconnectSocket();
        };
    }, [socket, connectSocket, disconnectSocket]);
    const sendMessage = () => {
        if (message.trim() && socket) {
            socket.emit("sendMessage", { text: message });
            setMessage("");
        }
    };
    return (
        <div>
            <h1>Chat</h1>
            <div>
                {messages.map((msg, index) => (
                    <p key={index}>{msg.text}</p>
                ))}
            </div>
            <input
                type="text"
                value={message}
                onChange={(e) => setMessage(e.target.value)}
            />
            <button onClick={sendMessage}>Send</button>
            <h2>Online Users</h2>
            <ul>
                {onlineUsers.map((userId) => (
                    <li key={userId}>{userId}</li>
                ))}
            </ul>
        </div>
    );
};
export default Chat;

5. 运行应用程序

  • 启动后端服务器:
node index.js
  • 启动 React 开发服务器:
npm start

访问http://localhost:5173以查看聊天应用程序。您可以打开多个选项卡或浏览器来测试实时消息传递和在线用户跟踪。

概括

本文演示:

  1. 在 MERN 堆栈应用程序中设置 Socket.IO 服务器。
  2. 使用有针对性的广播消息。
  3. 处理用户的连接和断开连接。
  4. 将实时功能集成到 React 前端。

可以通过添加私人消息、聊天室或使用 MongoDB 的消息持久化等功能来随意扩展该项目。

本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/55165.html

(0)

相关推荐

发表回复

登录后才能评论