socket.io 始终有连接 false

socket.io always has connection false

以下是我目前的情况。构造函数里面的注释也是三种不同的尝试

目前,当前端启动时,它将在 socket.io 中继续尝试与后端连接。好在后台确实收到了连接,坏处是前端一直认为断开连接,一直在重连。


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);
                });
            }
        });
    }

控制台日志中的套接字是这样的。即使调用 'this.socket.connect()'.

,'connected' 属性也不会改变

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: (...)

如果出现问题,请告诉我。非常感谢!

更新: 经过一番排查,发现同一个页面的多个连接是由reconnection:true引起的。连接在前端创建后立即自行关闭,但后端只有在超时时才会关闭它。

我通过执行以下步骤解决了这个问题:

  1. 放弃 socket.io-client 并转移到 ngx-socket-io。如果我们使用 Angular 前端,我猜我们不应该直接使用 socket.io-client。

这样做之后,我发现浏览器上的控制台开始弹出cors错误。并且

  1. 我为服务器端套接字io初始化添加了白名单。


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
    }
});

完成后,此时一切正常

希望这对某人有所帮助。