Intro
Until last time, I had used node-web-rtc to try WebRTC.But because the example was a little complicated for I understood the core functions of using WebRTC.
So I look for other frameworks or libraries.
PeerJS is a famous library for WebRTC.
peers/peerjs: Peer-to-peer data in the browser. - GitHub
peers/peerjs-server: Server for PeerJS - GitHub
PeerJS - Simple peer-to-peer with WebRTC
A problem is I don't know how to integrate to the Nest.js project.
I couldn't find examples.
So I don't choose at least this time.
What shall I choose?
According MDN, WebRTC doesn't specify strictly what technology is used on server application for connecting two devices.
Signaling and video calling - Web APIs | MDN
But in many examples include MDN's one use WebSocket.
samples-server/s/webrtc-from-chat at master · mdn/samples-server · GitHub
So I try WebSocket in the Nest.js project.
Use WebSocket in a Nest.js project
Nest.js has a function for using WebSocket.It can use socket.io and ws.
Because its last update date is more recently, and it is more simpler than socket.io, I choose ws this time.
websockets/ws: Simple to use, blazing fast and thoroughly tested WebSocket client and server for Node.js - GitHub
ws/ws.md at master · websockets/ws · GitHub
Adapter - Gateways | NestJS - A progressive Node.js framework
Install
npm install --save @nestjs/websockets @nestjs/platform-ws npm install --save-dev @types/ws
Add gateway
To route WebSocket accesses, I add gateway what named "events".Gateways | NestJS - A progressive Node.js framework
nest g gateway events
It creates two files(events.gateway.ts, events.gateway.spec.ts).
In events.gateway.ts has WebSocket by default.
events.gateway.ts
import { SubscribeMessage, WebSocketGateway } from '@nestjs/websockets';
@WebSocketGateway()
export class EventsGateway {
@SubscribeMessage('message')
handleMessage(client: any, payload: any): string {
return 'Hello world!';
}
}
There are samples for using WebSocket with socket.io and ws.
According to the sample of ws, I change main.ts and events.gateway.ts.
nest/sample/16-gateways-ws at master · nestjs/nest · GitHub
events.gateway.ts
import { SubscribeMessage, WebSocketGateway, WebSocketServer, WsResponse } from '@nestjs/websockets';
import { Server } from 'ws';
import { Observable, from } from 'rxjs';
import { map } from 'rxjs/operators';
@WebSocketGateway()
export class EventsGateway {
@WebSocketServer()
server: Server;
@SubscribeMessage('message')
handleMessage(client: any, payload: any): Observable<WsResponse<number>> {
return from([1, 2, 3]).pipe(map(item => ({ event: 'events', data: item })));
}
}
main.ts
import { NestFactory } from '@nestjs/core';
import { WsAdapter } from '@nestjs/platform-ws';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useWebSocketAdapter(new WsAdapter(app));
await app.listen(3000);
}
bootstrap();
Adapter
Because I forgot adding adapter into main.ts, an error occured like below.No driver (WebSockets) has been selected. In order to take advantage of the default driver, please, ensure to install the "@nestjs/platform-socket.io" package ($ npm install @nestjs/platform-socket.io).
Client
For Firefox and Chrome, I don't need install anything to use WebSocket.rtc-sample.ts
export class RtcSample {
public tryWebSocket(){
// Replace XXX.XXX.XXX.XXX to server PC's IP address
const ws = new WebSocket('ws://XXX.XXX.XXX.XXX:3000');
ws.onopen = () => {
ws.send(JSON.stringify({
event: 'message',
data: 'test',
}));
};
ws.onmessage = data => {
console.log(data);
};
}
...
}
Because I want to access from my phone, so I use IP address to create WebSocket instance.When I start, I can get three messages.
MessageEvent {isTrusted: true, data: "{"event":"events","data":1}", origin: "ws://XXX.XXX.XXX.XXX:3000", lastEventId: "", source: null, …} MessageEvent {isTrusted: true, data: "{"event":"events","data":2}", origin: "ws://XXX.XXX.XXX.XXX:3000", lastEventId: "", source: null, …} MessageEvent {isTrusted: true, data: "{"event":"events","data":3}", origin: "ws://XXX.XXX.XXX.XXX:3000", lastEventId: "", source: null, …}
Send messages to connected clients
A problem is the message is only sent to client who accessed and sent message.Though two clients(ex. clientA and clientB) have connected the server, when clientA sends a message and only clientA receives a message from server.
How to get connected clients?
The server instance has them.
events.gateway.ts
import { SubscribeMessage, WebSocketGateway, WebSocketServer, WsResponse } from '@nestjs/websockets';
import { Server } from 'ws';
import { Observable, from } from 'rxjs';
import { map } from 'rxjs/operators';
@WebSocketGateway()
export class EventsGateway {
@WebSocketServer()
server: Server;
@SubscribeMessage('message')
handleMessage(client: any, payload: any): Observable<WsResponse<number>> {
console.log(this.server.clients.size);
const sendData = { event: 'message', data: 'hello world!!' };
this.server.clients.forEach(s => {
s.send(JSON.stringify(sendData));
});
return from([1, 2, 3]).pipe(map(item => ({ event: 'events', data: item })));
}
}
"s" is WebSocket.Though I can set "sendData" as the argument of s.send() directly, it is caused a runtime exception.
So I convert to JSON string.
This code sends messages to all clients.
If I want to only send to another client, I can compare with "client" of handleMessage's argument.
events.gateway.ts
...
@WebSocketGateway()
export class EventsGateway {
...
@SubscribeMessage('message')
handleMessage(client: any, payload: any): Observable<WsResponse<number>> {
console.log(this.server.clients.size);
const sendData = { event: 'message', data: 'hello world!!' };
this.server.clients.forEach(s => {
if (s == client) {
return;
}
s.send(JSON.stringify(sendData));
});
return from([1, 2, 3]).pipe(map(item => ({ event: 'events', data: item })));
}
}
References
The WebSocket API (WebSockets) - Web APIs | MDNGateways | NestJS - A progressive Node.js framework
websockets/ws: Simple to use, blazing fast and thoroughly tested WebSocket client and server for Node.js - GitHub
WebRTC API - Web APIs | MDN
コメント
コメントを投稿