Masquitos
Masquitos

Reputation: 536

Angular 6 authentificate client after server restart socket.io socketio-jwt

Id like to auth eacht socket.io event on server side. When i open angular page first, call method initSocket(login: Login), its ok. Authentification successfull and i can send a message to server. But if i restart server, angular reconnect to server by Htttp, but cant send a message by socketio. In my server no messages in logs. It seems that socketio-jwt block an clients message. If i press F5 on client side its still ok again. How to solve it without refreshing a page? It seems taht i have to pass a token to each event on client side, after connection established to, but i dont know how to do it.

Angular 6:

    public initSocket(login: Login): void {
    this.socket = socketIo(SERVER_URL);
    console.log('Socket init at' + SERVER_URL);
    this.socket.emit('authenticate', { token: this.login.token });
    this.socket.on('authenticated', function () {
        console.log('socket is jwt authenticated');
    });
    this.socket.on('unauthorized', function (error, callback) {
        if (error.data.type === 'UnauthorizedError' || error.data.code === 'invalid_token') {
            // redirect user to login page perhaps or execute callback:
            callback();
            console.error('Users token has expired');
        }
    });

    this.socket.on('disconnect', function (error) {
        console.error('socket disconnect', error);
    });

    this.socket.on('connect_failed', function (error) {
        console.error('socket connect_failed');
    });
}

Server side:

io.sockets
.on('connection', socketioJwt.authorize({
    secret: environment.secret,
    timeout: 15000,
    callback: false
})).on('authenticated', function (socket) {
    clients[socket.decoded_token.id] = socket.decoded_token.login;
    console.error('Connected: ', socket.decoded_token.login);

    socket.on('message', async function (data) {
        try {
            // Проверка что пользователь пишите от себя
            if (data.from === socket.decoded_token.id) {
                data.totalCount = await db_helper.saveMessage(data);
                if (clients[data.from] && clients[data.to]) {
                    io.sockets.connected[clients[data.to].socket].emit("message", data);
                    console.log("Sending from: " + clients[data.from].name + " to: " + clients[data.from].name + " '" + data.text + "'");
                } else {
                    console.log('User does not exist: from=>', data.from, ':', clients[data.from], 'to=>', data.to, ':', clients[data.to]);
                }
            }
        }
        catch (error) {
            console.error(error.message);
        }
    });

    //Removing the socket on disconnect
    socket.on('disconnect', function () {
    });
});

enter image description here

Upvotes: 2

Views: 1550

Answers (1)

Ramakant Singh
Ramakant Singh

Reputation: 121

This is because whenever your server/client goes offline, a new socket is created for re connection purpose and to establish a new connection i.e re connection, Server disconnects all it's previous connection from the same client, this process is asynchronous and thus is not visible to developers easily.

I would have also checked if my socket reconnection which is done is reconnected to the , by default socket reconnects to the port your client is connected to.

if that's the case then you need to reconnect with the help of io (socket manager)

There is also a possibility that your client re connection is set to false, you can check your socket properties by consoling it as follows:

this.socket.on('disconnect', function (error) {
    console.log('disconnected', this)
    //this sets whether the re connection is allowed or not
    this.io._reconnection = true;
});

this.socket.on('reconnect', (error, callback) => {
    console.log('reconnect succesfully', this);
    //connect to the previously connected socket.
    this.io.socket.reconnect()
});

Upvotes: 2

Related Questions