使用 Socket.io 在 Angular SSR 中代理 WebSocket 连接的分步指南

前几天,我需要准备一个 Angular 应用程序,以便使用 Socket.io 代理向我们的 API 后端发送 HTTP 查询和聊天服务的 WebSocket 连接。在网上查了不少信息后,事情就变得简单明了了,让我们来看看如何操作。

首先,我们需要深入研究 Angular 配置: 如果之前没有做过,请在 src 目录下创建 proxy.conf.mjs 文件。请勿使用 proxy.conf.json,因为它只允许对一种上下文进行设置。在我们的例子中,我们需要为至少两种路由设置代理:

1. 以 /api 开头的路径,这将是调用 HTTP 协议 API 的后台路径,例如

  • 登录的 POST 请求:http://localhost:3000/api/login
  • 或获取已登录用户配置文件的 GET 查询:http://localhost:3000/api/profile/me

2. 和/socket.io 前缀的请求,这将是我们的 WebSocket 路径。客户端发出的第一个请求是 HTTP 请求,用于协商连接参数。一旦完成,通信就会切换到 WebSocket 协议。Socket.io 客户端使用的默认 URL 将是 ${DOMAIN}/socket.io/?….
请确保您使用的模式与后端相同。

为什么需要这样做?

当前台和后台应用程序不在同一地点时(这种情况经常发生),这样做非常有用。

从 localhost:4200 的前台发出的所有 HTTP 调用都将重定向到后端,后端监听的是自己的 URL,即 localhost:3000。在 Docker 环境中,这将是你的容器主机名。

同样,WebSocket 流也需要声明,以便代理。客户端发起的通信通过 URL localhost:4200 发送,到达 localhost:3000。ws 协议略有不同,但我已经见过使用 http 方案的配置。使用这种方式也没关系,只需将 ws 替换为 http 即可。我们的后台希望使用 ws 协议建立 ws 通信,这就是我这样定制的原因。

因此,我们需要配置 Angular,使其知道如何以及在何处传递从后台发送和接收的数据。

proxy.conf.mjs 应该如下所示:

export default [
  {
    context: [‘/socket.io/’],
    target: ‘ws://localhost:3000/’,
    ws: true,
    loglevel: ‘debug’,
    secure: false,
 },
 {
    context: [‘/api’],
    target: ‘http://localhost:3000',
    secure: false,
    loglevel: ‘debug’,
 },
];
  • context 是需要跟踪的 URI。
  • target 是重定向流的位置,如果不重写路径,URL 将是 target + context。
  • ws 选项允许代理 WebSocket 请求;将其设为 true 可用于 /socket.io 上下文。
  • 日志级别非常明确,在调试模式下,您会看到调用的轨迹,但在生产模式下,别忘了移除日志级别。

您还必须设置 angular.json 文件,以便将 proxy.conf.mjs 与应用程序绑定。

…
"serve": {
  "builder": "@angular-devkit/build-angular:dev-server",
  "configurations": {
     "production": {
        "buildTarget": "frontend:build:production",
        "proxyConfig": "src/proxy.conf.mjs"
      },
      "development": {
         "buildTarget": "frontend:build:development",
         "proxyConfig": "src/proxy.conf.mjs"
      }
  },
  "defaultConfiguration": "development"
},
…

最后,将 WebSocket 连接到 Angular 应用程序。这里使用的是 ngx-socket-io 软件包,别担心,它只是 Socket.io 客户端的一个叠加;API 经过简化,与 Angular 兼容:

import { Injectable } from '@angular/core';
import { Socket } from 'ngx-socket-io';

@Injectable({
  providedIn: 'root',
})
export class SocketService extends Socket {
  public constructor() {
    super({
      url: 'ws://localhost:4200/',
      options: {},
    });
  }
  …
}

作者:Aude LELLOUCHE

本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/48954.html

(0)

相关推荐

发表回复

登录后才能评论