socket.io always has connection false

Viewed 701

The following is what I have at this moment. The comments inside the constructor are also three different tries.

For now, when the frontend launches, it will keep trying to connect with the backend in socket.io. The good thing is the backend did receive the connection, the bad thing is the frontend always counts it as disconnected and keeps reconnecting.


import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { io, Socket } from 'socket.io-client';
import { environment } from 'environments/environment';
import { Observable, Subject } from 'rxjs';


@Injectable({
    providedIn: 'root'
})
export class GeneralService {

    base = environment.profileGeneratebaseUrl;
    apiUrl = environment.apiUrl;
    baseUrl = environment.baseUrl;

    private socket: Socket;

    // Observable string sources
    private emitChangeSource = new Subject<any>();
    // Observable string streams
    changeEmitted$ = this.emitChangeSource.asObservable();

    /**
     * Constructor
     */
    constructor(private _httpClient: HttpClient) {
        const token = localStorage.getItem('access_token');
        const userId = localStorage.getItem('userId');
        const timeout = 5000;
        // // will create 5 or more rooms
        // if (token) {
        //     console.log('token: ', token);
        //     const socket = io(this.baseUrl, {
        //       reconnection: true,
        //       timeout: timeout,
        //       query: {token: token}
        //     });

        //     this.socket = socket;

        //     this.socket.on("connect", function () {
        //         // socket.close();
        //         console.log('token sent: ', token);
        //         socket
        //             .emit("authenticate", { token: token })
        //             .on("authenticated", () => {
        //             console.log("authorized");
        //             // socket.close();
        //             })
        //             .on("unauthorized", (msg) => {
        //             console.log(`unauthorized: ${JSON.stringify(msg.data)}`);
        //             throw new Error(msg.data.type);
        //             });
        //         if (userId) {
        //             socket.emit("join", ['user-' + userId.toString()])
        //         }

        //         socket.on("get sessionID", (data) => {
        //             console.log("sessionID: ", data.sessionId);
        //         });
        //     });
        // }
        if (token) {
            this.formSocketIOConnectionWithAccessToken();
        }

        // not working
        // if (userId) {
        //     const socket = io(this.baseUrl, {
        //       reconnection: true,
        //       timeout: timeout,
        //       query: {token: userId}
        //     });

        //     this.socket = socket;

        //     this.socket.on("connect", function () {
        //         // socket.close();
        //         socket
        //             .emit("sign in", userId)
        //             .on("get sessionID", res => {
        //                 console.log("authorized");
        //                 console.log("res: ", res);
        //                 // socket.close();
        //             })
        //             .on("unauthorized", (msg) => {
        //             console.log(`unauthorized: ${JSON.stringify(msg.data)}`);
        //             throw new Error(msg.data.type);
        //             });
        //         if (userId) {
        //             socket.emit("join", ['user-' + userId.toString()])
        //         }

        //         socket.on("get sessionID", (data) => {
        //             console.log("sessionID: ", data.sessionId);
        //         });
        //     });
        // }

        
        // const token = localStorage.getItem("tri-token");
        // const timeout = 5000;
        // const socket = io(this.baseUrl, {
        //     reconnection: true,
        //     timeout: timeout,
        //     query: {token: token},
        // });
        // console.log('socket assigned');

        // this.socket = socket;
        // console.log('socket set');

        // this.socket.on("connect", function () {
        //     console.log('connected');
        //     // socket.close();
        //     socket
        //         .emit("authenticate", { token: token })
        //         .on("authenticated", () => {
        //             console.log("authorized");
        //             // socket.close();
        //         })
        //         .on("unauthorized", (msg) => {
        //             console.log(`unauthorized: ${JSON.stringify(msg.data)}`);
        //             throw new Error(msg.data.type);
        //         });

        //     socket.on("get sessionID", (data) => {
        //         console.log("sessionID: ", data.sessionId);
        //     });
        // });
    }


    // /**
    //  * connect to socket.io when log in
    //  *
    //  */

    public async formSocketIOConnectionWithAccessToken() {
        console.log('formSocketIOConnectionWithAccessToken is triggered');
        const token = localStorage.getItem("access_token");
        const timeout = 30000;
        console.log('this.socket: ', this.socket);
        return new Promise<void>((resolve, reject) => {
            if (token && (!this.socket || this.socket['disconnected'])) {
                const socket = io(this.baseUrl, {
                    reconnection: true,
                    timeout: timeout,
                    query: { token: token }
                });
    
                this.socket = socket;
    
                this.socket.connect();
    
                console.log('this.socket: ', this.socket);
    
                this.socket.on("connect", function () {
                    // socket.close();
                    console.log('connected');
    
                    socket
                        .emit("authenticate", { token: token })
                        .on("authenticated", () => {
                            console.log("authorized");
                            // socket.close();
                            return resolve();
                        })
                        .on("unauthorized", (msg) => {
                            console.log(`unauthorized: ${JSON.stringify(msg.data)}`);
                            return reject(new Error(msg.data.type));
                        });
    
                    socket.on("get sessionID", (data) => {
                        console.log("sessionID: ", data.sessionId);
                    });
                });
            }
            else {
                return reject();
            }
        })
    }



    listen(eventName: string) {
        console.log('this.socket: ', this.socket);
        return new Observable<any>((subscriber) => {
            if (this.socket && !this.socket['disconnected']) {
                this.socket.on(eventName, (data) => {
                    subscriber.next(data);
                });
            }
            else if (this.socket && this.socket['disconnected']) {
                this.socket.connect();
                console.log('this.socket2: ', this.socket);
                this.socket.on(eventName, (data) => {
                    subscriber.next(data);
                });
            }
        });
    }

The socket in console log is like this. The 'connected' attribute won't change even after calling 'this.socket.connect()'.


this.socket:  
Socket {receiveBuffer: Array(0), sendBuffer: Array(0), ids: 0, acks: {…}, flags: {…}, …}
acks: {}
connected: false
disconnected: true
flags: {}
ids: 0
io: Manager {nsps: {…}, subs: Array(1), opts: {…}, _reconnection: true, _reconnectionAttempts: Infinity, …}
nsp: "/"
receiveBuffer: []
sendBuffer: []
subs: (4) [ƒ, ƒ, ƒ, ƒ]
_callbacks: {$connect: Array(1), $user info updated: Array(1), $talent folder updated: Array(1), $folder list updated: Array(6)}
active: (...)
volatile: (...)

Please let me know if something goes wrong. Much appreciate!

UPDATE: After some investigation, it turns out that the multiple connections from the same page is caused by reconnection:true. The connection closes itself as soon as it was created on the frontend, but the backend would close it only when it times out.

1 Answers

I solved this problem by doing the following steps:

  1. Giving up socket.io-client and moving to ngx-socket-io. Guess we should not use socket.io-client directly if we are using an Angular frontend.

After doing so, I found that the console on the browser starts popping up cors errors. And

  1. I added the white list for the server-side socket io initialization.


const io = socketio(http, {
    pingTimeout: 30000,
    pingInterval: 5000,
    upgradeTimeout: 30000, // default value is 10000ms, try changing it to 20k or more
    cors: {
        origin: whitelist // array of strings
    }
});

After doing so, everything works fine at this moment.

Hope this could help someone.

Related