Traverse2023 / traverse-ui

2 stars 1 forks source link

Create Socket.io Infrastructure #13

Open iao233 opened 1 year ago

iao233 commented 1 year ago
  1. Create Socket.io connection between client and server with attaching a userId to the socket.
  2. Create 2 example requests where the user is identified with that userId in 2 different namespaces
  3. Create a request where a message is being sent by one user but then is being received by a different user.

Client:

// UserA's connection
const socketUserA = io('http://your-server-url', {
    query: {
        userId: 'UserA',
    },
});

// UserB's connection
const socketUserB = io('http://your-server-url', {
    query: {
        userId: 'UserB',
    },
});

// Chat namespace
const chatSocket = io('http://your-server-url/chat', {
    query: {
        userId: 'UserA', // The sender's user ID (UserA)
    },
});

// Notification namespace
const notificationSocket = io('http://your-server-url/notification', {
    query: {
        userId: 'UserB', // The sender's user ID (UserB)
    },
});

// Sending a chat message from UserA to UserB
chatSocket.emit('chat-message', 'Hello, UserB!', 'UserB');

// Sending a notification from UserB to UserA
notificationSocket.emit('send-notification', 'New notification', 'UserA');

Server:

const http = require('http');
const server = http.createServer();
const io = require('socket.io')(server);

// Store user information and sockets in a Map for easy access
const userSockets = new Map();

io.on('connection', (socket) => {
    // Handle user authentication and user ID assignment (this is a simplified example)
    const userId = socket.handshake.query.userId;
    if (!userId) {
        // Disconnect the socket if no user ID is provided
        socket.disconnect(true);
        return;
    }

    // Store the socket with the user ID for later use
    userSockets.set(userId, socket);

    // Handle user-specific events
    socket.on('disconnect', () => {
        // Remove the user's socket when they disconnect
        userSockets.delete(userId);
    });
});

const chatNamespace = io.of('/chat');
const notificationNamespace = io.of('/notification');

chatNamespace.on('connection', (socket) => {
    socket.on('chat-message', (message, recipientUserId) => {
        const senderUserId = socket.handshake.query.userId;

        // Find the recipient's socket using their user ID
        const recipientSocket = userSockets.get(recipientUserId);

        if (recipientSocket) {
            // Send the chat message to the recipient
            recipientSocket.emit('chat-message', message, senderUserId);
        }
    });
});

notificationNamespace.on('connection', (socket) => {
    socket.on('send-notification', (notification, recipientUserId) => {
        const senderUserId = socket.handshake.query.userId;

        // Find the recipient's socket using their user ID
        const recipientSocket = userSockets.get(recipientUserId);

        if (recipientSocket) {
            // Send the notification to the recipient
            recipientSocket.emit('receive-notification', notification, senderUserId);
        }
    });
});

server.listen(3000, () => {
    console.log('Socket.io server is running on port 3000');
});
iao233 commented 1 year ago

In the future, for push notifications, after msg is stored in mongodb with storage service, send socket notification (with chatRoom, channel, and senderName) back to a navbar component listening to notificationSocket. It will only be add to front end notification list if the url is not currently the chatroom and the user logged in is not the sender of the msg.

iao233 commented 1 year ago

Infrastructure has been set up. Implementation can begin. (sendFriendRequest already completely onboarded)