Socket.io acknowledgement in Nest.js

Simply use the return statement from SubscribeMessage

// server
@SubscribeMessage('message')
  async onMessage(
    client: Socket, query: string
  ) {
    try {
      console.log(query) 
      return 'hello'
    } catch (e) {
      // ...
    } 
  }

on the client side use as third param a function

// client
this.socket.emit('message', query, (res) => {
  console.log(res); // should log 'hello'
});

After short time researching NestJS. Here is my solution.

src
├── app.controller.spec.ts
├── app.controller.ts
├── app.module.ts
├── common
│   └── adapters
│       └── ws-adapter.ts
├── events
│   ├── events.gateway.ts
│   └── events.module.ts
└── main.ts

main.ts File

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { WsAdapter } from './common/adapters/ws-adapter.ts';
import * as cors from 'cors';

let corsOptions = {
    origin: 'http://nestjs.test',
    credentials: true
}

async function bootstrap() {
    const app = await NestFactory.create(AppModule);
    app.useWebSocketAdapter(new WsAdapter(3000));
    app.use(cors(corsOptions));
    await app.listen(4000);
}
bootstrap();

Because when we using WebSocket Adapter we can't use same port with NestJS application anymore.

common\adapters\ws-adapter.ts File

import * as WebSocket from 'ws';
import { WebSocketAdapter } from '@nestjs/common';
import { IoAdapter } from '@nestjs/websockets';
import { MessageMappingProperties } from '@nestjs/websockets';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/observable/empty';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/filter';

export class WsAdapter extends IoAdapter {
  public bindMessageHandlers(
    client,
    handlers: MessageMappingProperties[],
    process: (data: any) => Observable<any>,
  ) {
    handlers.forEach(({ message, callback }) => {
        client.on('event', function (data, ack) {
            console.log('DATA', data)
            ack('woot')
        })
        Observable.fromEvent(client, message)
            .switchMap(data => process(callback(data)))
            .filter(result => !!result && result.event)
            .subscribe(({ event, data }) => client.emit(event, data))
        });
  }
}

My Client side source code

socket.emit('event', {data: 'some data'}, function (response) {
    console.log('RESPONSE', response)
});
socket.on('event', function(data) {
    console.log('ON EVENT', data);
});

And here is my result

enter image description here

enter image description here

Hope this help!!