HarmonyOS鸿蒙Next中相同的链接地址同时链接两个websocket,第二个链接后第一个会收到code 1000

HarmonyOS鸿蒙Next中相同的链接地址同时链接两个websocket,第二个链接后第一个会收到code 1000 相同的链接地址, 同时链接两个 websocket 第二个链接后,第一个会收到 code 1000

6 回复

开发者你好

本地使用ws创建服务端,websocket创建两个链接,并未复现code 1000的问题,code码为1000是正常关闭。

能否确认下是否是服务端限制导致的问题。

本地测试代码:

import webSocket from '@ohos.net.webSocket';
import { BusinessError } from '@kit.BasicServicesKit'

@Entry
@Component
struct Index{
  ws1:webSocket.WebSocket | null = null
  ws2:webSocket.WebSocket | null = null
  defaultIpAddress = 'ws://localhost:3000'

  build() {
    Column() {
      Button('创建链接1').onClick((event: ClickEvent) => {
        this.ws1 = webSocket.createWebSocket();

        this.ws1?.on('open', (err: BusinessError, value: Object) => {
          console.log('on open, status:' + JSON.stringify(value));
          // 当收到on('open')事件时,可以通过send()方法与服务器进行通信
          this.ws1?.send('Hello, server!', (err: BusinessError, value: boolean) => {
            if (!err) {
              console.log('Message sent successfully');
            } else {
              console.log('Failed to send the message. Err:' + JSON.stringify(err));
            }
          });
        });
        this.ws1?.on('message', (err: BusinessError, value: string | ArrayBuffer) => {
          console.log('on message, message:' + value);
          // 当收到服务器的`bye`消息时(此消息字段仅为示意,具体字段需要与服务器协商),主动断开连接
          if (value === 'bye') {
            this.ws1?.close((err: BusinessError, value: boolean) => {
              if (!err) {
                console.log('Connection closed successfully');
              } else {
                console.log('Failed to close the connection. Err: ' + JSON.stringify(err));
              }
            });
          }
        });
        this.ws1?.on('close', (err: BusinessError, value: webSocket.CloseResult) => {
          console.log('on close, code is ' + value.code + ', reason is ' + value.reason);
        });
        this.ws1?.on('error', (err: BusinessError) => {
          console.log('on error, error:' + JSON.stringify(err));
        });
        this.ws1?.connect(this.defaultIpAddress, (err: BusinessError, value: boolean) => {
          if (!err) {
            console.log('Connected successfully');
          } else {
            console.log('Connection failed. Err:' + JSON.stringify(err));
          }
        });
      });
      Button('创建链接2').onClick((event: ClickEvent) => {
        this.ws2 = webSocket.createWebSocket();

        this.ws2?.on('open', (err: BusinessError, value: Object) => {
          console.log('on open, status:' + JSON.stringify(value));
          // 当收到on('open')事件时,可以通过send()方法与服务器进行通信
          this.ws2?.send('Hello, server!', (err: BusinessError, value: boolean) => {
            if (!err) {
              console.log('Message sent successfully');
            } else {
              console.log('Failed to send the message. Err:' + JSON.stringify(err));
            }
          });
        });
        this.ws2?.on('message', (err: BusinessError, value: string | ArrayBuffer) => {
          console.log('on message, message:' + value);
          // 当收到服务器的`bye`消息时(此消息字段仅为示意,具体字段需要与服务器协商),主动断开连接
          if (value === 'bye') {
            this.ws2?.close((err: BusinessError, value: boolean) => {
              if (!err) {
                console.log('Connection closed successfully');
              } else {
                console.log('Failed to close the connection. Err: ' + JSON.stringify(err));
              }
            });
          }
        });
        this.ws2?.on('close', (err: BusinessError, value: webSocket.CloseResult) => {
          console.log('on close, code is ' + value.code + ', reason is ' + value.reason);
        });
        this.ws2?.on('error', (err: BusinessError) => {
          console.log('on error, error:' + JSON.stringify(err));
        });
        this.ws2?.connect(this.defaultIpAddress, (err: BusinessError, value: boolean) => {
          if (!err) {
            console.log('Connected successfully');
          } else {
            console.log('Connection failed. Err:' + JSON.stringify(err));
          }
        });
      });
    };
  }
}

ws代码:

const WebSocket = require('ws');

// 创建 WebSocket 服务器,监听 3000 端口
const wss = new WebSocket.Server({ port: 3000 });

console.log('WebSocket 服务器已启动,监听 3000 端口...');

// 当有客户端连接时触发
wss.on('connection', (ws, request) => {
  console.log('客户端已连接');

  // 接收客户端消息
  ws.on('message', (data) => {
    console.log('收到消息:', data.toString());

    // 回复消息给客户端
    ws.send(`服务器收到: ${data}`);
  });

  // 可选:发送一条欢迎消息
  ws.send('欢迎连接到 WebSocket 服务器!');

  // 当客户端断开连接时
  ws.on('close', () => {
    console.log('客户端已断开连接');
  });
});

更多关于HarmonyOS鸿蒙Next中相同的链接地址同时链接两个websocket,第二个链接后第一个会收到code 1000的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


服务端可能设计了连接限制策略,例如同一客户端(或同一IP、同一用户标识)只允许保持一个活跃的 WebSocket 连接。

当第二个连接建立时,服务端检测到第一个连接已存在,为了释放资源或避免冲突,主动关闭了第一个连接,并发送状态码 1000 表示正常关闭。

建议在建立新连接前,确保已正确关闭旧连接。

多数 WebSocket 服务器(尤其长连接服务)会限制同一客户端 IP 或同一 Session ID 的并发连接数。当第二个连接建立时,服务器可能主动关闭第一个连接(发送 code 1000)以释放资源。

状态码 1000 表示连接正常关闭。

| 1000 | CLOSE_NORMAL | 正常关闭; 无论为何目的而创建,该链接都已成功完成任务。 |

可能的原因:

1、可能服务端做了单连接/IP限制

尝试解决:

1、使用一个单例websocket实例,避免重复创建连接。 2、服务端修改连接策略

在HarmonyOS Next中,同一地址同时建立两个WebSocket连接时,第二个连接建立会导致第一个连接收到1000状态码(正常关闭)。这是系统层面的资源管理机制,防止同一地址重复占用连接资源。

在HarmonyOS Next中,同一个URL同时建立两个WebSocket连接时,第一个连接收到1000状态码(CLOSE_NORMAL)是符合WebSocket协议规范的预期行为。

WebSocket协议设计上,通常不建议对同一端点(相同URL、协议和身份验证)建立多个并行连接。当第二个连接成功建立时,服务器或客户端框架可能会主动关闭第一个连接,以确保资源合理使用和状态一致性。

可能的原因和机制:

  1. 服务器端限制:许多WebSocket服务器实现(包括常用后端框架)会限制同一客户端的并发连接数,新连接建立时会关闭旧连接。

  2. 客户端资源管理:HarmonyOS的WebSocket实现可能包含连接池管理机制,相同标识的连接可能会被复用或替换。

  3. 协议层处理:1000状态码表示正常关闭,说明连接是被主动终止而非错误导致。

建议的解决方案:

  • 如果需要多个连接,考虑使用不同的URL或连接参数区分会话
  • 实现连接管理器,避免创建重复连接
  • 检查服务器端配置,调整并发连接策略
  • 在收到1000状态码后,按正常关闭流程处理连接释放和重连逻辑

这种情况通常不需要修改HarmonyOS系统配置,而是通过调整应用层的连接管理策略来解决。

回到顶部