你需要安装哪个socket.io版本以使Server类的“of”方法在Typescript中工作?

huangapple go评论73阅读模式
英文:

Which socket.io version do I have to install to make works the method "of" from Server class with Typescript?

问题

I'm setting up my sockets handlers for my web server in nestJS.
All my npm modules are at the latest version with 0 vulnerability.

In all my gateways, I have this following problem:

For each line "io.of("random namespace")", my nest logger gives me this error:

nest_container   | TypeError: io.of is not a function

3 days ago I didn't have this error.

my socket.io version: "version": "4.5.3"
my typescript version: "version": "4.9.4"

Here is my code:

import { MessageBody, SubscribeMessage, WebSocketGateway, WebSocketServer, ConnectedSocket, OnGatewayConnection, OnGatewayDisconnect, OnGatewayInit } from "@nestjs/websockets";
import { Server as SocketIOServer, Socket, Namespace } from '@nestjs/platform-socket.io/node_modules/socket.io';
import { Logger, UseGuards } from "@nestjs/common";
import { AuthGuard } from "@nestjs/passport";
import { MessageService } from "./message/message.service";
import { MessageEntity } from "./message/message.entity";
import * as jsrsasign from 'jsrsasign';

interface MessageChat {
    room: string;
    isChannel: boolean;
    content?: string;
}

interface MessageToSend {
    sender?: string;
    room: string;
    content: string;
}

@WebSocketGateway({transports: ['websocket'], namespace: '/chat'})
export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect {
    private server: SocketIOServer;
    private logger: Logger = new Logger('ChatGateway');
    private chatNamespace: Namespace;

    constructor(
        private messageService: MessageService,
    ) 
    {}

    private socketMap: Map<string, string> = new Map<string, string>();

    @UseGuards(AuthGuard('websocket'))
    handleConnection(client: Socket) {
        if (client.handshake.auth['token'] != null) {
            let pseudo = jsrsasign.KJUR.jws.JWS.parse(client.handshake.auth['token']).payloadObj!.login;
            this.socketMap.set(pseudo, client.id);
            this.logger.log(`${pseudo} is connected`);
            console.log(this.socketMap);
        }
    }

    afterInit(server: SocketIOServer) {
        this.server = new SocketIOServer();
        this.chatNamespace = server.of('chat');
        this.logger.log('Init');
    }

    handleDisconnect(client: Socket) {
        if (client.handshake.auth['token'] != null) {
            let pseudo = jsrsasign.KJUR.jws.JWS.parse(client.handshake.auth['token']).payloadObj!.login;
            this.socketMap.delete(pseudo);
            this.logger.log(`${pseudo} is disconnected`);
        }
    }

    @SubscribeMessage('addMessage')
    handleNewMessage(@MessageBody() blop: MessageChat, @ConnectedSocket() client: Socket) {
        let pseudo = "unknown";
        let token = client.handshake.query.token;
        if (client.handshake.auth['token'] != null) {
            pseudo = jsrsasign.KJUR.jws.JWS.parse(client.handshake.auth['token']).payloadObj!.login;
        }
        let sender: string = client.id;
        this.socketMap.set(pseudo, sender);
        console.log('ChatGateway::handleNewMessage : ', blop, pseudo);
        let data: MessageEntity = {
            id: undefined,
            room: blop.room,
            isChannel: blop.isChannel,
            sender: pseudo,
            content: blop.content,
            date: undefined
        }
        this.messageService.create(data);
        let toSend : MessageToSend = {sender: pseudo, room: blop.room, content: blop.content};
        if (!blop.isChannel)
        {
            client.emit('selfMessage', toSend);
            let socketDest = this.socketMap.get(blop.room);
            if (socketDest != undefined)
            {
                console.log("message", blop.room, pseudo, blop.content);
                this.logger.log(socketDest);
                console.log(toSend);
                console.log(this.chatNamespace.sockets);
                this.chatNamespace.sockets.get(socketDest).emit('messagePrivate', toSend);
                this.logger.log("msg send");
            }
        }
        else
        {
            this.messageService.findByChannel(blop.room).then((data) => console.log(data));
        }
    }

    @SubscribeMessage('history')
    handleHistory(@MessageBody() data: MessageChat, @ConnectedSocket() client: Socket) {
        if (data.isChannel)
        {
            this.messageService.findByChannel(data.room).then((data) => client.emit("history", data));
        }
        else
        {
            let pseudo = jsrsasign.KJUR.jws.JWS.parse(client.handshake.auth['token']).payloadObj!.login;
            this.messageService.findByPrivate(data.room, pseudo).then((data) => client.emit("history", data));
        }
    }
}

This is my log from nest:

nest_container   | /usr/src/app/nest_project/src/chat/chat.gateway.ts:46
nest_container   |         this.chatNamespace = server.of('chat');
nest_container   |                                     ^
nest_container   | TypeError: server.of is not a function
nest_container   |     at ChatGateway.afterInit (/usr/src/app/nest_project/src/chat/chat.gateway.ts:46:37)
nest_container   |     at ConsumerObserver.next (/usr/src/app/nest_project/node_modules/rxjs/src/internal/Subscriber.ts:161:25)
nest_container   |     at SafeSubscriber.Subscriber._next (/usr/src/app/nest_project/node_modules/rxjs/src/internal/Subscriber.ts:119:22)
nest_container   |     at SafeSubscriber.Subscriber.next (/usr/src/app/nest_project/node_modules/rxjs/src/internal/Subscriber.ts:75:12)
nest_container   |     at ReplaySubject._subscribe (/usr/src/app/nest_project/node_modules/rxjs/src/internal/ReplaySubject.ts:80:18)
nest_container   |     at ReplaySubject.Observable._trySubscribe (/usr/src/app/nest_project/node_modules/rxjs/src/internal/Observable.ts:244:19)
nest_container   |     at ReplaySubject.Subject._trySubscribe (/usr/src/app/nest_project/node_modules/rxjs/src/internal/Subject.ts:113:31)

I maybe found the problem,
when I call the "of" method of my Server class, somehow the compiler is getting confused and is trying to call the "of" function of the rxjs module...

Is it possible, and how can I avoid that?

英文:

I'm setting up my sockets handlers for my web server in nestJS.
All my npm modules are at the latest version with 0 vulnerability.

In all my gateways, I have this following problem :

For each line &quot;io.of(&quot;/random namespace&quot;)&quot;, my nest logger gives me this error :

nest_container   | TypeError: io.of is not a function

3 days ago I didn't have this error.

my socket.io version :  &quot;version&quot;: &quot;4.5.3&quot;
my typescript version :  &quot;version&quot;: &quot;4.9.4&quot;

Here is my code :

import { MessageBody, SubscribeMessage, WebSocketGateway, WebSocketServer, ConnectedSocket, OnGatewayConnection, OnGatewayDisconnect, OnGatewayInit } from &quot;@nestjs/websockets&quot;;
import { Server as SocketIOServer, Socket, Namespace } from &#39;@nestjs/platform-socket.io/node_modules/socket.io&#39;;
import { Logger, UseGuards } from &quot;@nestjs/common&quot;;
import { AuthGuard } from &quot;@nestjs/passport&quot;;
import { MessageService } from &quot;./message/message.service&quot;;
import { MessageEntity } from &quot;./message/message.entity&quot;;
import * as jsrsasign from &#39;jsrsasign&#39;;
interface MessageChat {
room: string;
isChannel: boolean;
content?: string;
}
interface MessageToSend {
sender?: string;
room: string;
content: string;
}
@WebSocketGateway({transports: [&#39;websocket&#39;], namespace: &#39;/chat&#39;})
export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect {
private server: SocketIOServer;
private logger: Logger = new Logger(&#39;ChatGateway&#39;);
private chatNamespace: Namespace;
constructor(
private messageService: MessageService,
) 
{}
private socketMap: Map&lt;string, string&gt; = new Map&lt;string, string&gt;;
@UseGuards(AuthGuard(&#39;websocket&#39;))
handleConnection(client: Socket) {
if (client.handshake.auth[&#39;token&#39;] != null) {
let pseudo = jsrsasign.KJUR.jws.JWS.parse(client.handshake.auth[&#39;token&#39;]).payloadObj!.login;
this.socketMap.set(pseudo, client.id);
this.logger.log(`${pseudo} is connected`);
console.log(this.socketMap);
}
}
afterInit(server: SocketIOServer) {
this.server = new SocketIOServer();
this.chatNamespace = server.of(&#39;chat&#39;);
this.logger.log(&#39;Init&#39;);
}
handleDisconnect(client: Socket) {
if (client.handshake.auth[&#39;token&#39;] != null) {
let pseudo = jsrsasign.KJUR.jws.JWS.parse(client.handshake.auth[&#39;token&#39;]).payloadObj!.login;
this.socketMap.delete(pseudo);
this.logger.log(`${pseudo} is disconnected`);
}
}
@SubscribeMessage(&#39;addMessage&#39;)
handleNewMessage(@MessageBody() blop: MessageChat, @ConnectedSocket() client: Socket) {
let pseudo = &quot;unknow&quot;;
let token = client.handshake.query.token;
if (client.handshake.auth[&#39;token&#39;] != null) {
pseudo = jsrsasign.KJUR.jws.JWS.parse(client.handshake.auth[&#39;token&#39;]).payloadObj!.login;
}
let sender: string = client.id;
this.socketMap.set(pseudo, sender);
console.log(&#39;ChatGateway::handleNewMessage : &#39;, blop, pseudo);
let data: MessageEntity = {
id: undefined,
room: blop.room,
isChannel: blop.isChannel,
sender: pseudo,
content: blop.content,
date: undefined
}
this.messageService.create(data);
let toSend : MessageToSend = {sender: pseudo, room: blop.room, content: blop.content};
if (!blop.isChannel)
{
client.emit(&#39;selfMessage&#39;, toSend);
let socketDest = this.socketMap.get(blop.room);
if (socketDest != undefined)
{
console.log(&quot;message&quot;, blop.room, pseudo, blop.content);
this.logger.log(socketDest);
console.log(toSend);
console.log(this.chatNamespace.sockets);
//this.chatNamespace = this.server.of(&#39;/chat&#39;);
this.chatNamespace.sockets.get(socketDest).emit(&#39;messagePrivate&#39;, toSend);
//this.server.sockets.sockets.get(socketDest).emit(&quot;messagePrivate&quot;, toSend);
this.logger.log(&quot;msg send&quot;);
}
//this.messageService.findByPrivate(blop.room, pseudo).then((data) =&gt; console.log(data));
}
else
{
this.messageService.findByChannel(blop.room).then((data) =&gt; console.log(data));
}
}
@SubscribeMessage(&#39;history&#39;)
handleHistory(@MessageBody() data: MessageChat, @ConnectedSocket() client: Socket) {
if (data.isChannel)
{
this.messageService.findByChannel(data.room).then((data) =&gt; client.emit(&quot;history&quot;, data));
}
else
{
let pseudo = jsrsasign.KJUR.jws.JWS.parse(client.handshake.auth[&#39;token&#39;]).payloadObj!.login;
this.messageService.findByPrivate(data.room, pseudo).then((data) =&gt; client.emit(&quot;history&quot;, data));
}
}
// // @UseGuards(AuthGuard(&#39;jwt&#39;))
// @SubscribeMessage(&#39;privateMessage&#39;)
// async handlePrivateEvent(@MessageBody() data: MessageChat, @ConnectedSocket() client: Socket): Promise&lt;void&gt; {
//     let pseudo = jsrsasign.KJUR.jws.JWS.parse(client.handshake.auth[&#39;token&#39;]).payloadObj;
//     console.log(pseudo, client.id, data.room, data.content);
//     client.emit(&#39;message&#39;, { sender: client.id, room: data.room, content: data.content });          
// }
}

This is my log from nest :

nest_container   | /usr/src/app/nest_project/src/chat/chat.gateway.ts:46
nest_container   |         this.chatNamespace = server.of(&#39;chat&#39;);
nest_container   |                                     ^
nest_container   | TypeError: server.of is not a function
nest_container   |     at ChatGateway.afterInit (/usr/src/app/nest_project/src/chat/chat.gateway.ts:46:37)
nest_container   |     at ConsumerObserver.next (/usr/src/app/nest_project/node_modules/rxjs/src/internal/Subscriber.ts:161:25)
nest_container   |     at SafeSubscriber.Subscriber._next (/usr/src/app/nest_project/node_modules/rxjs/src/internal/Subscriber.ts:119:22)
nest_container   |     at SafeSubscriber.Subscriber.next (/usr/src/app/nest_project/node_modules/rxjs/src/internal/Subscriber.ts:75:12)
nest_container   |     at ReplaySubject._subscribe (/usr/src/app/nest_project/node_modules/rxjs/src/internal/ReplaySubject.ts:80:18)
nest_container   |     at ReplaySubject.Observable._trySubscribe (/usr/src/app/nest_project/node_modules/rxjs/src/internal/Observable.ts:244:19)
nest_container   |     at ReplaySubject.Subject._trySubscribe (/usr/src/app/nest_project/node_modules/rxjs/src/internal/Subject.ts:113:31)

I maybe found the problem,
when i call the "of" method of my Server class, somehow the compiler is getting confused and is trying to call the "of" function of the rxjs module...

Is it possible, and how can i avoid that ?

答案1

得分: 1

我最终决定停止使用socket.io的命名空间功能,相关函数根本无法正常工作。

将所有socket存储在一个map容器中更简单且有效。

@WebSocketGateway({ transports: ['websocket'], namespace: '/chat' })
export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
    @WebSocketServer() server: SocketIOServer;
    private logger: Logger = new Logger('ChatGateway');

    constructor(
        private messageService: MessageService,
    ) {}

    private socketMap: Map<string, Socket> = new Map<string, Socket>();

    @UseGuards(AuthGuard('websocket'))
    handleConnection(client: Socket) {
        if (client.handshake.auth['token'] != null) {
            let pseudo = jsrsasign.KJUR.jws.JWS.parse(client.handshake.auth['token']).payloadObj!.login;
            this.socketMap.set(pseudo, client);
            this.logger.log(`${pseudo} is connected`);
        }
    }

    handleDisconnect(client: Socket) {
        if (client.handshake.auth['token'] != null) {
            let pseudo = jsrsasign.KJUR.jws.JWS.parse(client.handshake.auth['token']).payloadObj!.login;
            this.socketMap.delete(pseudo);
            this.logger.log(`${pseudo} is disconnected`);
        }
    }

    @UseGuards(AuthGuard('websocket'))
    @SubscribeMessage('addMessage')
    handleNewMessage(@MessageBody() blop: MessageChat, @ConnectedSocket() client: Socket) {
        let pseudo = "unknow";
        if (client.handshake.auth['token'] != null) {
            pseudo = jsrsasign.KJUR.jws.JWS.parse(client.handshake.auth['token']).payloadObj!.login;
        }
        this.socketMap.set(pseudo, client);
        console.log('ChatGateway::handleNewMessage : ', blop, pseudo);
        let data: MessageEntity = {
            id: undefined,
            room: blop.room,
            isChannel: blop.isChannel,
            sender: pseudo,
            content: blop.content,
            date: undefined
        }
        this.messageService.create(data);
        let toSend: MessageToSend = { sender: pseudo, room: blop.room, content: blop.content };
        if (!blop.isChannel) {
            client.emit('selfMessage', toSend);
            let socketDest = this.socketMap.get(blop.room);
            if (socketDest != undefined) {
                console.log("message", blop.room, pseudo, blop.content);
                socketDest.emit("messagePrivate", toSend);
                this.logger.log("msg send");
            }
        } else {
            // 其他操作...
        }
    }
}
英文:

I finally decided to stop using the namespace feature of socket.io, the associate functions are just not working.

Stocking all the entire sockets in a map container is easier and it just works.

@WebSocketGateway({transports: [&#39;websocket&#39;], namespace: &#39;/chat&#39;})
export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
@WebSocketServer() server: SocketIOServer;
private logger: Logger = new Logger(&#39;ChatGateway&#39;);
constructor(
private messageService: MessageService,
) 
{}
private socketMap: Map&lt;string, Socket&gt; = new Map&lt;string, Socket&gt;;
@UseGuards(AuthGuard(&#39;websocket&#39;))
handleConnection(client: Socket) {
if (client.handshake.auth[&#39;token&#39;] != null) {
let pseudo = jsrsasign.KJUR.jws.JWS.parse(client.handshake.auth[&#39;token&#39;]).payloadObj!.login;
this.socketMap.set(pseudo, client);
this.logger.log(`${pseudo} is connected`);
}
}
handleDisconnect(client: Socket) {
if (client.handshake.auth[&#39;token&#39;] != null) {
let pseudo = jsrsasign.KJUR.jws.JWS.parse(client.handshake.auth[&#39;token&#39;]).payloadObj!.login;
this.socketMap.delete(pseudo);
this.logger.log(`${pseudo} is disconnected`);
}
}
@UseGuards(AuthGuard(&#39;websocket&#39;))
@SubscribeMessage(&#39;addMessage&#39;)
handleNewMessage(@MessageBody() blop: MessageChat, @ConnectedSocket() client: Socket) {
let pseudo = &quot;unknow&quot;;
if (client.handshake.auth[&#39;token&#39;] != null) {
pseudo = jsrsasign.KJUR.jws.JWS.parse(client.handshake.auth[&#39;token&#39;]).payloadObj!.login;
}
this.socketMap.set(pseudo, client);
console.log(&#39;ChatGateway::handleNewMessage : &#39;, blop, pseudo);
let data: MessageEntity = {
id: undefined,
room: blop.room,
isChannel: blop.isChannel,
sender: pseudo,
content: blop.content,
date: undefined
}
this.messageService.create(data);
let toSend : MessageToSend = {sender: pseudo, room: blop.room, content: blop.content};
if (!blop.isChannel)
{
client.emit(&#39;selfMessage&#39;, toSend);
let socketDest = this.socketMap.get(blop.room);
if (socketDest != undefined)
{
console.log(&quot;message&quot;, blop.room, pseudo, blop.content);
socketDest.emit(&quot;messagePrivate&quot;, toSend);
this.logger.log(&quot;msg send&quot;);
}
}
else (...)

huangapple
  • 本文由 发表于 2023年3月3日 17:59:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75625590.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定