HarmonyOS 鸿蒙Next中webSocket连接失败

HarmonyOS 鸿蒙Next中webSocket连接失败 Android项目中使用okhttp的websocket通信,代码如下,主要就是有3个header参数。

fun initSocketConnect(mListener: WebSocketListener): WebSocket {
    val currentTime = System.currentTimeMillis()
    val lastLeaveTime = MMKVUtil.decodeLong(CHAT_DESTROY_TIME)
    val httpClient = OkHttpClient().newBuilder()
        .writeTimeout(5, TimeUnit.SECONDS)
        .readTimeout(5, TimeUnit.SECONDS)
        .connectTimeout(5, TimeUnit.SECONDS)
        .build()
    val request = Request.Builder().url(HttpUrlUtil.BASE_SOCKET_URL)
        .addHeader("X-Access-Token", UserUtil.getUserInfo()?.token ?: "-1")
        .addHeader("isVIP", AppUtil.isWifiProxy())
        .addHeader("enterTime", (currentTime - lastLeaveTime).toString())
    return httpClient.newWebSocket(request.build(), mListener)
}

写ArkTs的时候使用webSocket组件访问同样的网络,代码如下,connect方法返回true,但是马上就会回调ws.on(‘error’,(err) => {})这里,对应的err信息是:on error, error:{“code”:200,“data”:“502”}。

private ws: webSocket.WebSocket | null = null


    this.ws = webSocket.createWebSocket()
    this.ws.on('open', (err, value) => {
      LogUtil.warn("on open, status:" + JSON.stringify(value));
    });
    this.ws.on('message', (err, value) => {
      LogUtil.warn("on message, message:" + value);
    });
    this.ws.on('close', (err, value) => {
      LogUtil.warn("on close, code is " + value.code + ", reason is " + value.reason);
    });
    this.ws.on('error', (err) => {
      LogUtil.warn("on error, error:" + JSON.stringify(err));
    });
    const token = UserUtil.getToken()
    let socketHeader: Record<string, Object> = {
      "isVIP": "8096",
      "X-Access-Token": token,
      "enterTime": "1200000",
    }

    let options: webSocket.WebSocketRequestOptions = {
      header: socketHeader,
      skipServerCertVerification: true
    }
    this.ws?.connect(
      HttpUrlConstants.BASE_SOCKET_URL,
      options,
      (err, value) => {
        LogUtil.warn("Connected Result.value=" + JSON.stringify(value) + "-----err=" + err);
      }
    )

还有就是不管我传不传options这个参数,都会立马回调’error’这里,感觉好像是options的header参数没有生效,有没有大佬知道这个是啥情况


更多关于HarmonyOS 鸿蒙Next中webSocket连接失败的实战教程也可以访问 https://www.itying.com/category-93-b0.html

10 回复

开发者您好,参考webSocket使用步骤和200错误码原因。根据您问题描述中的代码,您可核对一下是否是缺少了send步骤:

ws.send("Hello, server!", (err: BusinessError, value: boolean) => {
  if (!err) {
    console.info("Message send successfully");
  } else {
    console.error(`send fail. Code: ${err.code}, message: ${err.message}`);
  }
});
  • WebSocket使用步骤:
  1. 需要先通过createWebSocket方法创建WebSocket对象,然后通过connect方法连接到服务器。
  2. 当连接成功后,客户端会收到open()事件的回调,之后客户端就可以通过send()方法与服务器进行通信。
  3. 当服务器发信息给客户端时,客户端会收到on(‘message’)事件的回调。
  4. 当客户端不要此连接时,可以通过调用close()方法主动断开连接,之后客户端会收到close()事件的回调。
    若在上述任一过程中发生错误,客户端会收到on(‘error’)事件的回调。
  • 200错误码表示的是运行超时。
  • WebSocket属于http子协议,遵循http状态码。

WebSocket完整案例可参考:WebSocket客户端连接服务端完整案例

如果以上信息仍不能解决您的报错问题,建议提供一下完整的运行Hilog便于定位分析到原因。

更多关于HarmonyOS 鸿蒙Next中webSocket连接失败的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


connect成功之后(返回结果是true),没有收到open和message事件的回调,而是立马回调error事件

开发者您好,目前需要提供完整tcpdump+hilog日志进行分析,您可参考以下步骤获取日志上传到新楼层:

获取日志步骤

步骤一:先清理日志

1.hdc shell

2.cd data/log/hilog

3.hilog -w clear (清除多余日志)

4.exit 退回到目录

5.判断是否是log版本:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/hilog#查看log版本信息

如果是log版本参考步骤二,如果不是参考步骤三。

步骤二:log版本带有betaClub,可以使用如下方式抓取tcpdump+hilog:

一、登录betaClub

二、手机里面的实用工具里面有个betaclub工具,在BetaClub应用里打开TCP dump日志开关,打开日志开关路径:BetaClub->我的->系统设置->TCP dump日志开关。

三、复现问题

四、使用命令hdc file recv /data/log/tcpdump 本地路径,可以抓出tcpdump。

五、使用命令hdc file recv /data/log/hilog 导出hilog

六、提供问题复现时间点

步骤三:采用工具获取tcpdump包:

工具链接:https://developer.huawei.com/consumer/cn/doc/architecture-guides/tools-v1_2-ts_360-0000002510878920

抓出tcpdump后

使用命令hdc file recv /data/log/hilog 导出hilog

200 连接失败

错误信息

WebSocket connect failed.

错误描述

WebSocket连接失败。

可能原因

  1. 服务器拒绝客户端连接、协议出现问题导致握手失败或证书验证失败。
  2. 客户端或服务端断开连接时无状态码。

处理步骤

检查协议是否有效、证书校验是否通过,重新连接。

你参数类型对吗 为啥直接返回502

参数类型应该没有错误,都是string类型的

那你们这个502是啥意思,

header中X-Access-Token这个参数,如果过期了或者不是合法的都会报502,所以我感觉好像header中传递的参数服务器没有收到。

鸿蒙Next中WebSocket连接失败可能由网络权限、证书配置或服务端兼容性导致。检查应用是否已申请ohos.permission.INTERNET网络权限,并在module.json5中配置。若使用wss协议,需确认证书有效且服务端支持TLS协议。注意鸿蒙Next的WebSocket API基于ArkTS/ArkUI,需使用标准接口如WebSocket()创建连接,并确保URL格式正确(如ws://或wss://)。可排查防火墙或代理设置,同时验证服务端是否正常运行。

从你提供的代码来看,ArkTS端WebSocket连接失败并立即触发error回调,且错误信息为{"code":200,"data":"502"},这通常表明连接已建立但被服务器拒绝(502 Bad Gateway),问题很可能出在请求头(header)的设置上。

在HarmonyOS Next的@ohos.net.webSocket API中,WebSocketRequestOptionsheader字段要求值类型为Array<{key: string, value: string}>,而不是一个普通的对象(Record<string, Object>)。你当前的代码将header定义为了一个对象,这可能导致header参数没有被正确设置,从而服务器无法识别认证信息,返回了502错误。

修改建议:

socketHeader的定义和options的赋值修改为符合API规范的数组格式:

let socketHeader: Array<{key: string, value: string}> = [
  { key: "isVIP", value: "8096" }, // 注意:这里value需要是字符串,请确认你的逻辑
  { key: "X-Access-Token", value: token },
  { key: "enterTime", value: "1200000" }
];

let options: webSocket.WebSocketRequestOptions = {
  header: socketHeader, // 这里传入的是数组
  skipServerCertVerification: true
}

关键点说明:

  1. Header格式header必须是一个Array<{key: string, value: string}>。每个header项是一个明确包含keyvalue两个字符串属性的对象。
  2. 值类型value必须是string类型。请确保你传入的tokenenterTime的值是字符串。在你的原始Android代码中,enterTime是通过计算得到的Long类型,然后转换成了String。在ArkTS中也需要确保这一点。
  3. isVIP字段的值:在你的Android代码中,isVIP的值来自AppUtil.isWifiProxy(),这通常返回一个布尔值或数字,但在作为HTTP Header发送时,OkHttp会将其转换为字符串。在你的ArkTS示例中,你直接写死了"8096",请确认这个值是否符合业务逻辑。如果需要动态判断,应使用相应的ArkTS API获取代理状态并转换为字符串。
  4. 错误码解读code:200可能表示网络层连接已建立,但data:"502"表示应用层协议(WebSocket握手)失败,服务器返回了HTTP 502状态码。这强烈指向握手请求不符合服务器预期,缺失或错误的Header是常见原因。

修改后,WebSocket握手请求应该能携带正确的Header,从而通过服务器的验证。如果问题依旧,建议使用抓包工具(如Charles、Fiddler)对比修改前后ArkTS应用和Android应用发出的WebSocket握手请求(HTTP Upgrade请求),确认Header是否已正确发送。

回到顶部