首页 > 解决方案 > Socket.io:从两个房间配对而不重复配对?

问题描述

我正在研究使用 socket.io 的用户配对算法,它在 Node.js 上运行。我想确保当人们连接时不会发生重复配对。

算法步骤如下:

  1. 将玩家分成两个房间,一个用于零售商,另一个用于供应商。
  2. 当玩家进入其中一个房间时,我将从另一个房间获取套接字列表并将播放器与它的第一个套接字配对。
    • 如果配对成功,将两名玩家从房间中移除。
    • 如果失败(即另一个房间里没有人),则每五秒重试一次。

我不确定在获取房间的套接字列表的过程中是否会出现任何竞争条件问题。简而言之,是否有可能socketlist中的一个socket会被配对两次,并且两次配对都成功?

这是代码:

const wait = ms => new Promise(resolve => setTimeout(resolve, ms))

io.on('connection', (socket) => {
    console.log('New websocket connection', socket.id)

    socket.on('match', async (userId, role, classroomId) => {
        let roles = { 'retailer': 'supplier', 'supplier': 'retailer' }
        room = role + classroomId
        otherroom = roles[role] + classroomId

        socket.userId = userId
        socket.join(room)
        
        for (let i = 0; i < 60; ++i) {
            if (socket.rooms.has(room)) {
                const sockets = await io.in(otherroom).fetchSockets()
                
                if (sockets.length > 0
                    && io.sockets.sockets.get(socket[0].id).rooms.has(otherroom)) {
                    const teammate = io.sockets.sockets.get(sockets[0].id)
                    console.log(teammate.userId)
                    console.log(room, otherroom)
                    socket.leave(room)
                    teammate.leave(room)

                    const pair = await models.Pair.create({
                        supplierId: role == 'supplier' ? userId : teammate.userId,
                        retailerId: role == 'supplier' ? teammate.userId : userId,
                        currentTime: new Date().toISOString().slice(0, 10)
                    })
                    io.to(teammate.id).to(socket.id).emit('match-success', pair)
                    console.log((role == 'supplier' ? 's' : 'r'), pair)
                    break
                }
                
                console.log(socket.id, i)
                // if no match, rematch every 5 seconds.
                await wait(5000)
            } else {
                break
            }
        }

        socket.on('join', (room) => {
            console.log('join' + room)
            socket.join(room)
        })

        socket.on('leave', (room, callback) => {
            socket.leave(room)
            callback()
        })
    })
})

标签: javascriptalgorithmparallel-processingsocket.io

解决方案


推荐阅读