Closed dekavox closed 4 years ago
Please, use our Discord channel (support) for such questions. We are using GitHub to track bugs, feature requests, and potential improvements.
hi kamil, sorry for that, wasn't shure if this was a bug or not. thanks for the fast response. cheers
This still exists.
Is this the expected result? how do you get the sender client?
Yes, this still seem to exist and in my opinion this is clearly a bug.
When I found the bug I tried to dig into the nestJS modules but didn't really manage to find the cause of this problem. So I created this solution as a hack that works for me:
in ws-adapter-custom.ts
bindMessageHandler(
buffer: any,
handlers: MessageMappingProperties[],
process: (data: any) => Observable<any>,
wsClient: any,
): Observable<any> {
if (wsClient._receiver._opcode === 1) {
try {
const message = JSON.parse(buffer.data);
const messageHandler = WsAdapterCustom.handlers.find(
(handler) => handler.message === message.event,
);
if (!messageHandler) {
return EMPTY;
}
// hack to include wsClient into parameter of message-callback
// @ConnectedSocket() seems to give the wrong socket-instance at message-callback context
const messageData: any = {
wsClient,
message,
};
return process(messageHandler.callback(messageData));
} catch (_a) {
return EMPTY;
}
} else {
// no string payload
return EMPTY;
}
}
in message.gateway.ts
@SubscribeMessage('message-text')
async receiveTextMessage(@MessageBody() messageBody: any) {
let wsClient = messageBody.wsClient
let wsMessage = messageBody.message
}
Hope this solution works for you as well for now but ideally the @ConnectedSocket()
decorator should work like intended and give the correct socket instance.
I tried making a minimal reproduction on codesanbox as asked on Discord. It works for some reason.
Sandbox: https://codesandbox.io/s/pensive-lake-x9vfw
Steps:
var ws1 = new WebSocket(`ws://${location.host}?id=ws1`);
var ws2 = new WebSocket(`ws://${location.host}?id=wsw`);
ws1.send(JSON.stringify({ event: 'message', data: [] }));
ws2.send(JSON.stringify({ event: 'message', data: [] }));
I'm still investigating further if it's related to something else.
Cc: @kaupi1487
I think this is not a bug. If you use custom pipe than you must check the value in transform
method. Because websocket client object is passing from pipe too.
// zod-validation-pipe.ts
@Injectable()
export class ZodValidationPipe implements PipeTransform {
constructor(private schema: Schema) {}
async transform(value: any): Promise<any> {
console.log('>> 🚀 transform value:', typeof value, value);
if (value instanceof WsClient) {
return value;
}
// make your validation and return result in here...
}
Bug Report
hi together. I'm quite new to nest.js and typescript in general but so far I really like the concept behind it. I've been stuck with this problem for a few days now and I really would appreciate some help with this. so far I isolated the error to the following point.
Current behavior
i created a custom websocket adapter based on the websocket/ws package. so far it seems to be working properly but if I use a subscription and use the @ConnectedSocket() (or use the syntax without decorators stated out in the documentation) I always get the socket instance that connected first to my server but not the socket which sent the message.
Input Code
ws-adapter-custom.ts
message.gateway.ts
Expected behavior
the parameter wsClient of function messageStreamCreate should give back the proper socket instance of the sender of the message. instead the instance of the socket that connected first to my server is passed to the function (sockets were identified by the wsClient._socket.remotePort parameter)
Possible Solution
Environment