Nestjs socket.io即时通讯

在 Nest 中,网关只是一个用 @WebSocketGateway() 装饰器注解的类。从技术上讲,网关与平台无关,这使得它们在创建适配器之后就可以与任何 WebSockets 库兼容。有两个开箱即用的WS平台:socket.io和ws。你可以选择最适合你需要的。另外,您可以按照本指南构建自己的适配器。

官方文档:

https://docs.nestjs.com/websockets/gateways

1、nestjs中安装 socketIo对应模块

$ npm i --save @nestjs/websockets @nestjs/platform-socket.io
$ npm i --save-dev @types/socket.io
      

2、通过命令行工具生成gateway并配置socket

nest g gateway events
      

通过上面命令会在src目录下面生成events.gateway.js

这个里面可以自定义方法接受客户端广播

import { SubscribeMessage, WebSocketGateway, WsResponse, WebSocketServer } from '@nestjs/websockets';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators'
const l = console.log

@WebSocketGateway()
export class EventsGateway {
  @WebSocketServer() server;

  @SubscribeMessage('events')
  onEvent(client: any, payload: any): Observable> | any {
    // this.server.emit('resmsg', data);  // io.emit('resmsg', payload)
    let { name } = payload;
    if (name === 'ajanuw') {
      return of({
        event: 'events',
        data: {
          msg: 'hello ajanuw!'
        }
      })
    }
    if (name === 'alone') {
      return of('hi', '实打实')
        .pipe(
          map($_ =>
            ({
              event: 'events', data: {
                msg: $_
              }
            }))
        );
    }
    return of(payload);
  }

}
      

3、app.module.ts

app.module.ts
import { EventsGateway } from './events/events.gateway'
@Module({
  providers: [EventsGateway],
})
      

4、socket客户端


    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.1/socket.io.js"></script>
  <script>
    const l = console.log
    let socket = io('http://localhost:5000');
    socket.on('connect', function () {
      console.log('链接成功');

      // 发射
      socket.emit('events', {
        name: 'ajanuw'
      });

      // 发射
      socket.emit('events', {
        name: 'alone'
      });

      // 发射
      // socket.emit('identity', 0, (response) => console.log('Identity:', response));
    });
    
    // 监听
    socket.on('events', (data) => {
      l(data.msg)
    });
  </script>
  

5、分组广播和监听进入离开事件

  import { SubscribeMessage, WebSocketGateway,WebSocketServer} from '@nestjs/websockets';
  import { of } from 'rxjs';
  import * as url from "url"
  
  @WebSocketGateway()
  export class EventsGateway {
    @WebSocketServer() server;
    
    private clientsArr:any[]=[];
   
    handleConnection(client: any,){
      
      console.log('有人链接了'+client.id);   
   
    }
  
    handleDisconnect(client:any){
     
    }
    
    @SubscribeMessage('addCart')
    addCart(client: any, payload: any) {
         console.log(payload) 
      
        var roomid=url.parse(client.request.url,true).query.roomid;   /*获取房间号 获取桌号*/
        client.join(roomid);
        // this.server.to(roomid).emit('addCart','Server AddCart Ok');    //广播所有人包含自己
  
        client.broadcast.to(roomid).emit('addCart','Server AddCart Ok');   //不包括自己
  
  
    }
  
  }
  
 
客户端代码:


<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>socket.io</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.1/socket.io.js"></script>
</head>
<body>
<h1>socket.io的多房间1111</h1>
<input type="button" value="加入购物车" onclick="addCart()"><br>


</body>
</html>

<script type="text/javascript">

    //和服务器建立长连接
    var socket = io.connect('http://localhost:3000?roomid=1');

    //接收服务器返回的信息
    socket.on('addCart',function(data){

        console.log(data);
    });

    function addCart(){
        socket.emit('addCart','addCart');
    }

</script>