Reputation: 360
I want to inject @ConnectedSocket
into a nestjs service that provides an interface for event emitting. The goal is pretty clear - to avoid calling emit with raw event name and any
data. SocketFacadeHost
below is an example of such a service.
So far the only way I could think of is replacing each emit call by wrapping socket with a facade service factory - SocketFacade
.
socket.facade.ts
class SocketFacadeHost {
constructor(private client: Socket) { }
syncDSL(dsl: CoreDSL): void {
this.client.emit('syncDSL', dsl);
}
}
export const SocketFacade = (client: Socket) => new SocketFacadeHost(client);
socket.gateway.ts
...
@SubscribeMessage('bind')
async bindEnvironment(
@MessageBody() data: BindingDTO,
@ConnectedSocket() client: Socket,
): Promise<void> {
const { pageUUID } = data;
const page = await this.pagesService.getByUUID(pageUUID);
SocketFacade(client).syncDSL(page.coreDSL);
}
But that is still kinda hackish. Any straightforward way of doing this?
Something like extending @ConnectedSocket
decorator or WebSocketGateway
?
After going through tons of documentation, examples and issues on the subject, I believe the problem lies in the idea of making the service aware of context, that is by default incorrect. Thus guards, interceptors, pipes and all the ExecutionContext decorators only work on the controller/gateway level. Service should either be stateless or instantiated all over on each call (which is controlled by the @Injectable scope).
So my approach of using the facade factory is OK.
But then again, it would be convenient if it was possible to 'replace' @ConnectedSocket() decorator by a decorator that returns wrapped socket with an interface, that wouldn't mess with clean mvc.
Upvotes: 2
Views: 3067
Reputation: 360
In the end, I settled with hacking my own 'dependency injection'. Since request scope is not an option for WebSocketGateway
, I decided to manually instantiate and cleanup the needed services and store them within Socket
client with additional storage interface.
This way I have ConnectedSocket
-scoped classes that can communicate to one another, while still having an access to global scoped injections (that have to be manually passed down to all the classes through gateway).
Given approach solves all the problems, while keeping everything dry and in sync with the idea that some day ConnectedSocket
-scopes may be added to NestJS
.
Upvotes: 1