Socket connection from NextJS to a node backend - node.js

I am trying to implement a basic socket connection from my NextJS client side (running on localhost:3000) to my NestJs server (running on localhost:3003).
The server code looks like this
ChatGateway.ts
import {
SubscribeMessage,
WebSocketGateway,
OnGatewayInit,
WebSocketServer,
OnGatewayConnection,
OnGatewayDisconnect,
} from '#nestjs/websockets';
import {
Logger
} from '#nestjs/common';
import {
Socket,
Server
} from 'socket.io';
#WebSocketGateway()
export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect {
#WebSocketServer() server: Server;
private logger: Logger = new Logger('ChatGateway');
#SubscribeMessage('msgToServer')
handleMessage(client: Socket, payload: string): void {
console.log(payload);
this.server.emit('msgToClient', payload);
}
afterInit(server: Server) {
this.logger.log('Init');
}
handleDisconnect(client: Socket) {
this.logger.log(`Client disconnected: ${client.id}`);
}
handleConnection(client: Socket, ...args: any[]) {
this.logger.log(`Client connected: ${client.id}`);
this.server.emit('msgToClient', "payload");
}
}
ChatModule.ts
import { Module } from '#nestjs/common';
import { TypeOrmModule } from '#nestjs/typeorm';
import { ChatGateway } from "./chat.gateway";
#Module({
imports: [],
controllers: [],
providers: [ChatGateway],
})
export class ChatModule {}
AppModule.ts
#Module({
imports: [TypeOrmModule.forRoot(), NewsletterModule, AuthModule, UsersModule, ListingsModule, ChatModule]
})
export class AppModule {
constructor(private connection: Connection) {}
But when I try to connect to the socket from my client side
import {
io
} from "socket.io-client";
function Chat() {
const socket = io("http://127.0.0.1:3003");
useEffect(() => {
console.log("chat useEffect")
socket.emit('msgToServer', "message")
}, [])
socket.on('msgToClient', (message) => {
console.log(message)
})
I am not getting any errors, but also there is nothing happening when I emit or try to receive events from the server.
Even the server console doesnt log the emit events. The only thing that happens on the server is that the client gets connected and disconnected all the time without even me doing anything
Any idea why cant I connect to the sockets and why is the server constantly connecting and disconnecting even if I disable the socket connection form the client side.
Thanks!

Socket.io client needs to be version 2. Version 3 and 4 are breaking changes and don't communicate with a v2 server. Once Nest v8 hits, socket.io v4 will be used by default.

Related

How to resolve socket.io Error "TransportError: xhr poll error"

I want to make a socket.io server using NestJS.
I'm trying communication between server and client on localhost.
however, client(socket.io-client) throw the following error.
TransportError: xhr poll error
the server was running on localhost:3000. and the client was run from node command(node index.js)
server (mock.gateway.ts)
import { SubscribeMessage, WebSocketGateway, MessageBody, ConnectedSocket, WebSocketServer} from '#nestjs/websockets';
import { Socket } from 'socket.io';
#WebSocketGateway()
export class MockGateway {
#WebSocketServer()
server;
#SubscribeMessage('mock')
mock(
#MessageBody() data: string,
#ConnectedSocket() socket: Socket
): void {
console.log(data);
}
}
server (main.ts)
import { NestFactory } from '#nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
client
import { io, Socket } from 'socket.io-client';
const socket = io('ws://localhost:3000', {
path: '/socket.io',
});
socket.emit('mock', 'mock');
I tried set transports to the sockect.io-client. but it makes a timeout error.
import { io, Socket } from 'socket.io-client';
const socket = io('ws://localhost:3000', {
path: '/socket.io',
transports: ['websocket'],
});
socket.emit('mock', 'mock');
Maybe a mistake in module settings. so I use the wscat is debug-tool. It throws the following error, I'm wondering why wscat can connest Nest server.
$ wscat -c ws://localhost:3000/socket.io/\?transport=websocket
Connected (press CTRL+C to quit)
error: Invalid WebSocket frame: RSV1 must be clear
If anyone has any ideas, please comment.

Cannot start two instances of Microservice using package #golevelup/nestjs-rabbitmq

I would build a publish/subscribe message pattern between microservices using nestjs and rabbitmq. The problem with the built-in NestJS microservices Rabbitmq does not support pub/sub pattern,but it's easy to start multiple instances of microservice to test random queue message. And i tried to use #golevelup/nestjs-rabbitmq to implement the features. The problem with this package is that it seem like the port 3000 is the default using by the package and I don't know where and how I could change the port. I couldn't start multiple instances of consummers to test the pattern.
// Module Subcriber
import { RabbitMQModule } from '#golevelup/nestjs-rabbitmq';
import { Module } from '#nestjs/common';
import { SomeEventConsumerModule1Module } from './some-event-consumer-module1/some-event-consumer-module1.module';
#Module({
imports: [
RabbitMQModule.forRoot(RabbitMQModule, {
exchanges: [
{
name: 'amq.topic',
type: 'topic', // check out docs for more information on exchange types
},
],
uri: 'amqp://guest:guest#localhost:5672', // default login and password is guest, and listens locally to 5672 port in amqp protocol
// connectionInitOptions: { wait: false },
channels: {
'channel-1': {
prefetchCount: 15,
default: true,
},
'channel-2': {
prefetchCount: 2,
},
},
}),
SomeEventConsumerModule1Module,
],
})
export class EventsModule {}
Here is the service of Subscriber to get messesage from publisher.
// Service Subscriber
// imports
import { RabbitSubscribe } from '#golevelup/nestjs-rabbitmq';
import { Injectable } from '#nestjs/common';
import { ConsumeMessage, Channel } from 'amqplib'; // for type safety you will need to install package first
// ... so on
#Injectable()
export class SomeEventConsumerModule1Service {
constructor() {} // other module services if needs to be injected
#RabbitSubscribe({
exchange: 'amq.direct',
routingKey: 'direct-route-key', // up to you
queue: 'queueNameToBeConsumed',
errorHandler: (channel: Channel, msg: ConsumeMessage, error: Error) => {
console.log(error);
channel.reject(msg, false); // use error handler, or otherwise app will crush in not intended way
},
})
public async onQueueConsumption(msg: {}, amqpMsg: ConsumeMessage) {
const eventData = JSON.parse(amqpMsg.content.toString());
// do something with eventData
console.log(
`EventData: ${
eventData.bookName
}, successfully consumed!${amqpMsg.content.toString()}`,
);
}
// ... and in the same way
}
The here is the code of publisher
//app module
import { Module } from '#nestjs/common';
import { ClientsModule, Transport } from '#nestjs/microservices';
import { AppController } from './app.controller';
import { AppService } from './app.service';
#Module({
imports: [
ClientsModule.register([
{
name: 'GREETING_SERVICE',
transport: Transport.RMQ,
options: {
urls: ['amqp://localhost:5672'],
queue: 'queueNameToBeConsumed',
},
},
]),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
// App service
import { Inject, Injectable } from '#nestjs/common';
import { ClientProxy } from '#nestjs/microservices';
#Injectable()
export class AppService {
constructor(#Inject('GREETING_SERVICE') private client: ClientProxy) {}
async testEvent() {
this.client.emit('book-created', {
bookName: 'The Way Of Kings',
author: 'Brandon Sanderson',
});
}
}
the Error message display when trying to start the second instance
ERROR [Server] Error: listen EADDRINUSE: address already in use 127.0.0.1:3000
Error: listen EADDRINUSE: address already in use 127.0.0.1:3000
at Server.setupListenHandle [as _listen2] (node:net:1380:16)
at listenInCluster (node:net:1428:12)
at GetAddrInfoReqWrap.doListen (node:net:1567:7)
at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:85:8)
I don't know why the port 3000 is using by the service and how to change the port.

How to open port with Fastify?

I'm trying to use Fastify with my project, but when I want to start the server, it isn't opening the specific port.
I'm creating the server like this:
import { NestFactory } from "#nestjs/core";
import { NestFastifyApplication, FastifyAdapter } from "#nestjs/platform-fastify";
import { AppModule } from "./app.module";
async function bootstrap() {
const app = await NestFactory.create<NestFastifyApplication>(
AppModule,
new FastifyAdapter()
);
await app.listen(3000, '0.0.0.0');
}
bootstrap();
It says the application is successfully started, but when I check with netstat -ano,
the address(0.0.0.0:3000) isn't there.
The server logs:

ngx-socket-io Package is not work in angular JS

I was try use ngx-socket-io iPackage s not work in anguler JS
https://www.npmjs.com/package/ngx-socket-io Example But Not work.
let know any one if any other package to use in angular js.
npm install ngx-socket-io
Moddule.js
import { SocketIoModule, SocketIoConfig } from 'ngx-socket-io';
const config: SocketIoConfig = { url: 'http://localhost:8988', options: {} };
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
SocketIoModule.forRoot(config)
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
ChatService.js
import { Injectable } from '#angular/core
import { Socket } from 'ngx-socket-io'
#Injectable()
export class ChatService {
constructor(private socket: Socket) { }
assign_biker(biker_id){
this.socket.emit("assign_biker_order",{'biker_id:biker_id })
}
}
Do you Try socket client angular package ?
it so easy to use and worked in angular js.
Install first socket.io-client.
npm i socket.io-client
import * as io from 'socket.io-client';
private socket;
constructor() {
this.socket = io('here is your socket url');
}
assign_biker(biker_id){
this.socket.emit("assign_biker_order",{'biker_id:biker_id })
}

Using multiple sockets adapters with NestJS

I'm working on an Node.js application with NestJS. I need to communicate with 2 other apps.
The first one over WebSockets (Socket.io) and the other one over TCP sockets with net module.
Is it possible to use two gateways with specific adapters, one based on Socket.io and the other one on Net module, or do I have to split this application?
You don't need to split the application.
You can define your module as:
#Module({
providers: [
MyGateway,
MyService,
],
})
export class MyModule {}
with the gateway being in charge of the web sockets channel
import { SubscribeMessage, WebSocketGateway } from '#nestjs/websockets'
import { Socket } from 'socket.io'
...
#WebSocketGateway()
export class MyGateway {
constructor(private readonly myService: MyService) {}
#SubscribeMessage('MY_MESSAGE')
public async sendMessage(socket: Socket, data: IData): Promise<IData> {
socket.emit(...)
}
}
and the service being in charge of the TCP channel
import { Client, ClientProxy, Transport } from '#nestjs/microservices'
...
#Injectable()
export class MyService {
#Client({
options: { host: 'MY_HOST', port: MY_PORT },
transport: Transport.TCP,
})
private client: ClientProxy
public async myFunction(): Promise<IData> {
return this.client
.send<IData>({ cmd: 'MY_MESSAGE' })
.toPromise()
.catch(error => {
throw new HttpException(error, error.status)
})
}
}

Resources