[ ] Regression
[ ] Bug report
[X] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Adding these lines:
@WebSocketServer()
public socketServer: SocketIO.Server;
Results in this.socketServer
being null
in Component
s.
It would be awesome if one could get the native web socket server from everywhere. So I do not need to create a Gateway
everytime I want to emit a simple message.
Attribute is not null.
@Component()
export class SocketService {
// Only connections that are correctly authenticated get into this array
protected authenticatedConnections: Array<SocketConnection> = [];
// this is the SocketIO server (can be used for emit etc.)
@WebSocketServer()
public socketServer: SocketIO.Server;
}
Nest version: 4.6.7
For Tooling issues:
- Node version: 8
- Platform:
Others:
Honestly, it's not that easy. What if someone uses multiple gateways at the same time? IMO, you should inject a gateway to the component instead and pick up the server then.
I was having the same issue, but i had to inject it in one gateway, that gateway dose not do anything, you can think of it as wrapper around the underlying socket server, and then i used it as a dependency in another gateways. Idk if this the only way to do this, but it works :)
@kamilmysliwiec hi, I met a problem when I injected a WebSocketGateway. Here's the sample code.
// event.module.ts
import { Module } from '@nestjs/common'
import { EventGateway } from './event.gateway'
import { EventController } from './event.controller'
@Module({
providers: [EventGateway],
controllers: [EventController],
})
export class EventModule {}
// event.gateway.ts
import { SubscribeMessage, WebSocketGateway, WebSocketServer, WsResponse } from '@nestjs/websockets'
import { of, from, Observable } from 'rxjs'
import { map } from 'rxjs/operators'
import { Client, Server } from 'socket.io'
export const store: any = {}
@WebSocketGateway()
export class EventGateway {
@WebSocketServer()
server!: Server
@SubscribeMessage('action:join-room')
joinRoom(client: Client, room_name: string): Observable<WsResponse<string>> {
const socket = this.server.sockets.connected[client.id]
console.log(this.server.sockets.connected) // will print: { KUTCDbFhek0BS1YCAAAA: { ... }}
store.server = this.server
socket.join(room_name)
return of({ event: 'events', data: 'join room success' })
}
}
// event.controller.ts
import { Controller, Post, Inject, Body } from '@nestjs/common'
import { EventGateway, store } from './event.gateway'
@Controller()
export class EventController {
constructor(
private readonly eventGateway: EventGateway,
) {}
@Post('/v1/broadcast')
broadcast(@Body() body: string): string {
console.log(`broadcast something...`)
if (!store.server) {
console.log('no server')
} else {
console.log(store.server===this.eventGateway.server)
}
console.log(this.eventGateway.server.sockets.connected) // will print `{}`, it's empty
this.eventGateway.server
.to('default-room')
.emit('broadcast', `POST/broadcast is called. ${body}`)
return 'ok';
}
}
And my client could connect successfully to gateway, and could receive "join room success" after send action:join-room
message.
But when I call that /v1/broadcast
api, I found the server injected doesn't equal to that server which I cached in store
object, so the .sockets.connected
looks different. It's quite weird to me. Is it expected behavior? If yes, how could I get a singleton injectable instance?
And I tried @shekohex 's solution, to make EventController
and EventGateway
both depend on a seperated AnotherGateway
. And these two injected gateway are still different instances.
Hi, all.
I used socket.io-redis and socket.io-emitter to solve my problem. I could create a singleton server object by socket.io-redis, and it has same data source with the server created in WebSocketGateway.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
I was having the same issue, but i had to inject it in one gateway, that gateway dose not do anything, you can think of it as wrapper around the underlying socket server, and then i used it as a dependency in another gateways. Idk if this the only way to do this, but it works :)