🖌️
ngxs
  • 介绍
  • 入门
    • 为什么使用ngxs
    • 安装
  • 概念
    • 介绍
    • 存储(Store)
    • 动作(Actions)
    • 状态(State)
    • 选择(Select)
  • 高级
    • 动作处理程序
    • 动作的生命周期
    • 取消
    • 组合
    • 错误处理
    • Ivy迁移指南
    • 延迟加载
    • 生命周期
    • 映射子状态
    • 元归约器
    • 优化选择器
    • 选项
    • 共享状态
    • 状态令牌
    • 状态操作
    • 子状态
  • 菜单
    • 认证
    • 缓存
    • NGXS的组件事件
    • 防抖动动作
    • 动态插件
    • 不可变数据助手
    • 设计指南
    • 单元测试
  • 插件
    • 介绍
    • CLI
    • Logger
    • Devtools
    • Storage
    • Forms
    • Web Socket
    • Router
    • HMR
  • NGXS实验室
    • 介绍
  • 社区
    • FAQ
    • 资源
    • 贡献者
    • 贡献
    • 赞助商
  • 变更日志
Powered by GitBook
On this page
  • 安装
  • 配置
  • 用法

Was this helpful?

  1. 插件

Web Socket

将服务器Web套接字事件绑定到Ngxs存储操作。

安装

npm install @ngxs/websocket-plugin --save

# or if you are using yarn
yarn add @ngxs/websocket-plugin

配置

将NgxsWebsocketPluginModule插件添加到您的根应用程序模块中:

import { NgxsModule } from '@ngxs/store';
import { NgxsWebsocketPluginModule } from '@ngxs/websocket-plugin';

@NgModule({
  imports: [
    NgxsModule.forRoot([]),
    NgxsWebsocketPluginModule.forRoot({
      url: 'ws://localhost:4200'
    })
  ]
})
export class AppModule {}

该插件具有多种可以传递的选项:

  • url: Web套接字连接的网址。 可以在这里或通过ConnectWebsocket动作传递。

  • typeKey: 将Web套接字消息映射到操作类型的对象属性。 默认值:type

  • serializer: 将对象发送到Web套接字之前使用的序列化程序。 默认值: JSON.stringify

  • deserializer: 用于从Web套接字收到的消息的反序列化器。 默认值: JSON.parse

用法

连接后,Web套接字上出现的任何消息都将绑定到状态事件流。

假设服务器端Web套接字以以下格式向客户端发送消息:

{
  "type": "[Chat] Add message",
  "from": "Artur",
  "message": "Hello NGXS"
}

我们将要进行与此Web套接字消息相对应的操作,如下所示:

export class AddMessage {
  static type = '[Chat] Add message';
  constructor(public from: string, public message: string) {}
}

假设我们有一些messages状态,我们在其中存储聊天消息:

export interface Message {
  from: string;
  message: string;
}

@State<Message[]>({
  name: 'messages',
  defaults: []
})
@Injectable()
export class MessagesState {
  @Action(AddMessage)
  addMessage(ctx: StateContext<Message[]>, { from, message }: AddMessage) {
    const state = ctx.getState();
    // omit `type` property that server socket sends
    ctx.setState([...state, { from, message }]);
  }
}

我们可以通过调度带有效负载的 SendWebSocketMessage 来将消息发送到服务器。 让我们尝试一下:

@Component({ ... })
export class AppComponent {

  constructor(private store: Store) {}

  sendMessage(from: string, message: string) {
    const event = new SendWebSocketMessage({
      type: 'message',
      from,
      message
    });

    this.store.dispatch(event);
  }

}

发送消息时,请记住发送接受JSON对象。 服务器端的套接字将侦听message事件。 例如,服务器代码可以如下:

const { Server } = require('ws');
const { createServer } = require('http');

const app = require('express')();

const server = createServer(app);
const ws = new Server({ server });

server.listen(4200);

ws.on('connection', socket => {
  socket.on('message', data => {
    // That's the object that we passed into `SendWebSocketMessage` constructor
    const { type, from, message } = JSON.parse(data);

    if (type === 'message') {
      const event = JSON.stringify({
        type: '[Chat] Add message',
        from,
        message
      });

      // That's the same as `broadcast`
      // we want to send message to all connected
      // to the chat clients
      ws.clients.forEach(client => {
        client.send(event);
      });
    }
  });
});

请注意,您必须在服务器端指定 type 属性,否则将收到错误消息-Type ... not found on message。 如果您不想把type的属性名作为键名,可以在调用 forRoot 时指定自己的属性名称:

NgxsWebsocketPluginModule.forRoot({
  url: 'ws://localhost:4200',
  typeKey: 'myAwesomeTypeKey'
});

In order to kick off our websockets we have to dispatch the ConnectWebSocket action. This will typically happen at startup or if you need to authenticate before, after authentication is done. You can optionally pass the URL here.

为了开始我们的网络套接字,我们必须调度ConnectWebSocket动作。 这通常会在启动时发生,或者如果您需要在身份验证完成之前进行身份验证,则会发生这种情况。 您可以选择在此处传递URL。

@Component({ ... })
export class AppComponent {

  constructor(private store: Store) {}

  ngOnInit() {
    this.store.dispatch(new ConnectWebSocket());
  }

}

如果您在理解插件的工作方式时遇到困难,可以查看下面的数据流程图。 从一方面看,它似乎有点复杂,但不用担心。 只需遵循从视图开始到服务器端的粉红色数据流即可:

以下是您可以执行的所有动作的列表:

  • ConnectWebSocket: 要初始化Web套接字时请调度此动作。 可以在此处传递URL(可选)。

  • DisconnectWebSocket: 调度此动作来断开Web套接字的连接。

  • WebSocketConnected: 连接Web套接字时调度的操作。

  • WebSocketDisconnected: Web套接字断开连接时调度的动作。 使用其处理程序进行重新连接。

  • SendWebSocketMessage: 向服务器发送消息。

  • WebsocketMessageError: 收到消息时发生错误时,此插件调度的动作。

  • WebSocketConnectionUpdated: 在现有连接之上创建新连接时,此插件调度的操作。 现有连接正在关闭。

In summary - your server-side sockets should send objects that have a type property (or another key that you can provide in the typeKey property when calling forRoot). This plugin will receive a message from the server and dispatch the message as an action with the corresponding type value. If the type property doesn't match any client-side @Action methods (with an Action with the corresponding static type property value) then no State will respond to the message. 总而言之——您的服务器端套接字应发送具有type属性(或在调用forRoot 时可以在typeKey属性中提供的另一个键名)的对象。 该插件将从服务器接收一条消息,并使用相应的 type 值将该消息作为动作进行调度。如果 type 属性与任何客户端 @Action 方法都不匹配(带有具有相应 static type 属性值的动作),则没有状态会响应该消息。

PreviousFormsNextRouter

Last updated 4 years ago

Was this helpful?

NGXS WebSocket data flow