新连接导致当前连接停止工作

ve7v8dk2  于 2021-06-10  发布在  Redis
关注(0)|答案(1)|浏览(354)

我正在使用socket(我是新来的)和多租户结构并使用名称空间来制作聊天应用程序。这是我的密码:
套接字服务器:index.js

class Server {
    constructor() {
        this.port = process.env.PORT || 3000;
        this.host = process.env.HOST || `localhost`;

        this.app = express();
        this.http = http.Server(this.app);
        this.rootSocket = socketio(this.http);
    }

    run() {
        new socketEvents(this.rootSocket).socketConfig();
        this.app.use(express.static(__dirname + '/uploads'));
        this.http.listen(this.port, this.host, () => {
            console.log(`Listening on ${this.host}:${this.port}`);
        });
    }
}

const app = new Server();
app.run();

插座.js

var redis = require('redis');
var redisConnection = {
    host: process.env.REDIS_HOST,
    password: process.env.REDIS_PASS
};
var sub = redis.createClient(redisConnection);
var pub = redis.createClient(redisConnection);

class Socket {

    constructor(rootSocket) {
        this.rootIo = rootSocket;
    }

    socketEvents() {

        /**
         * Subscribe redis channel
         */
        sub.subscribe('visitorBehaviorApiResponse');
        //TODO: subscribe channel..

        // Listen to redis channel that published from api
        sub.on('message', (channel, data) => {
            data = JSON.parse(data);
            console.log(data);
            const io = this.rootIo.of(data.namespace);
            if (channel === 'visitorBehaviorApiResponse') {
                io.to(data.thread_id).emit('receiveBehavior', data);
                io.to('staff_room').emit('incomingBehavior', data);
            }
        })

        sub.on('error', function (error) {
            console.log('ERROR ' + error)
        })

        var clients = 0;
        this.rootIo.on('connection', (rootSocket) => {
            clients++;
            console.log('root:' + rootSocket.id + ' connected (total ' + clients + ' clients connected)');
            const ns = rootSocket.handshake['query'].namespace;

            // Dynamic namespace for multiple tenants
            if (typeof (ns) === 'string') {
                const splitedUrl = ns.split("/");
                const namespace = splitedUrl[splitedUrl.length - 1];
                const nsio = this.rootIo.of(namespace);
                this.io = nsio;

                this.io.once('connection', (socket) => {
                    var visitors = [];

                    console.log('new ' + socket.id + ' connected');

                    // once a client has connected, we expect to get a ping from them saying what room they want to join
                    socket.on('createChatRoom', function (data) {
                        socket.join(data.thread_id);
                        if (typeof data.is_staff !== 'undefined' && data.is_staff == 1) {
                            socket.join('staff_room');
                        } else {
                            if (visitors.some(e => e.visitor_id === data.visitor_id)) {
                                visitors.forEach(function (visitor) {
                                    if (visitor.visitor_id === data.visitor_id) {
                                        visitor.socket_ids.push(socket.id);
                                    }
                                })
                            } else {
                                data.socket_ids = [];
                                data.socket_ids.push(socket.id);
                                visitors.push(data);
                            }
                            socket.join('visitor_room');
                        }

                        //TODO: push to redis to check conversation type

                    });

                    socket.on('sendMessage', function (data) {
                        console.log(data);
                        pub.publish('chatMessage', JSON.stringify(data));
                        this.io.in(data.thread_id).emit('receiveMessage', data);
                        this.io.in('staff_room').emit('incomingMessage', data);
                        // Notify new message in room
                        data.notify_type = 'default';
                        socket.to(data.thread_id).emit('receiveNotify', data);
                    }.bind(this))

                    socket.on('disconnect', (reason) => {
                        sub.quit();
                        console.log('client ' + socket.id + ' left, ' + reason);
                    });

                    socket.on('error', (error) => {
                        console.log(error);
                    });

                });
            }

            // Root disconnect
            rootSocket.on('disconnect', function () {
               clients--;
               console.log('root:' + rootSocket.id + ' disconnected (total ' + clients + ' clients connected)');
            });
        });
    }

    socketConfig() {
        this.socketEvents();
    }
}
module.exports = Socket;

客户:

const server = 'https://socket-server'
    const connect = function (namespace) {
        return io.connect(namespace, {
           query: 'namespace=' + namespace,
           resource: 'socket.io',
           transports: ['websocket'],
           upgrade: false
        })
    }
    const url_string = window.location.href
    const url = new URL(url_string)
    const parameters = Object.fromEntries(url.searchParams)
    const socket = connect(`${server}/${parameters.shopify_domain}`)
    var handleErrors = (err) => {
      console.error(err);
    }

    socket.on('connect_error', err => handleErrors(err))
    socket.on('connect_failed', err => handleErrors(err))
    socket.on('disconnect', err => handleErrors(err))

我遇到的问题是,当socket服务器获得新连接时,现有连接将停止工作,直到它们刷新页面以重新连接新的socket.id。
当一个名称空间的客户机发出数据时,它会发送到其他名称空间,似乎我的代码在一个名称空间中不能正常工作。
你能看一下我的代码,告诉我哪里错了吗?
谢谢

xeufq47z

xeufq47z1#

1) Get UserId or accessToken while handshaking(in case of accessToken decrypt it).
 and store userID: socketId(in Redis or in local hashmap) depends upon the requirement .

2) When u are going to emit to particular user fetch the  socketid to that userid from redis or local hashmap
and emit to it.

**io.to(socketId).emit('hey', 'I just met you');**

3) If you are using multiple servers use sticky sessions

4) Hope this will help you

相关问题