英文:
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 "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 = "unknow";
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 = this.server.of('/chat');
this.chatNamespace.sockets.get(socketDest).emit('messagePrivate', toSend);
//this.server.sockets.sockets.get(socketDest).emit("messagePrivate", toSend);
this.logger.log("msg send");
}
//this.messageService.findByPrivate(blop.room, pseudo).then((data) => console.log(data));
}
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));
}
}
// // @UseGuards(AuthGuard('jwt'))
// @SubscribeMessage('privateMessage')
// async handlePrivateEvent(@MessageBody() data: MessageChat, @ConnectedSocket() client: Socket): Promise<void> {
// let pseudo = jsrsasign.KJUR.jws.JWS.parse(client.handshake.auth['token']).payloadObj;
// console.log(pseudo, client.id, data.room, data.content);
// client.emit('message', { 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('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 ?
答案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: ['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 (...)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论