HarmonyOS鸿蒙Next中这个库:https://gitcode.com/openharmony-tpc/openharmony_tpc_samples/tree/master/ohos_smack ;目前没有找到保持链接的相关逻辑比如ping或设置keepali

HarmonyOS鸿蒙Next中这个库:https://gitcode.com/openharmony-tpc/openharmony_tpc_samples/tree/master/ohos_smack ;目前没有找到保持链接的相关逻辑比如ping或设置keepali 【问题描述】:这个库:https://gitcode.com/openharmony-tpc/openharmony_tpc_samples/tree/master/ohos_smack ;目前没有找到保持链接的相关逻辑比如ping或设置keepalive的相关内容;这样导致连接会断开,帮忙看下有什么解决方案嘛?

【问题现象】:需求问题

【版本信息】:开发工具版本:6.0、手机系统版本:6.0、Api语言版本:20


更多关于HarmonyOS鸿蒙Next中这个库:https://gitcode.com/openharmony-tpc/openharmony_tpc_samples/tree/master/ohos_smack ;目前没有找到保持链接的相关逻辑比如ping或设置keepali的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

开发者你好,请问下你们具体是什么场景,需要实现什么效果?是需要给这个库提需求还是说有其他库的替代解决方案也可以呢。

您如果是想实现长连接在切换后台进行保活的效果的话,其他替代方案可以参考[@ohos.net.webSocket](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-websocket)库,使用长时任务保活websocket,应用退到后台会被杀掉进程,长时任务可以防止后台挂起的程序被杀掉。具体参考以下:

1.需要在module.json5配置文件的requestPermissions标签中声明后台运行权限。

{
    "name": "ohos.permission.KEEP_BACKGROUND_RUNNING",
    "reason": "$string:module_desc",
    "usedScene": {
        "abilities": [
            "EntryAbility"
        ],
        "when": "always"
    }
}

2.在module.json5中为需要使用长时任务的UIAbility声明相应的长时任务类型。

"module": {
     "abilities": [
         {
             "backgroundModes": [
              // 长时任务类型的配置项(可以指定多种)
             "audioRecording",
             "location"
             ], 
         }
     ],
     ...
 }

3.websocket长连接对应的长时任务类型可以选择voip类型,参考示例如下:

import { webSocket } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { backgroundTaskManager } from '@kit.BackgroundTasksKit';
import { wantAgent, WantAgent } from '@kit.AbilityKit';

let defaultIpAddress = "ws://xxxxxx:xxxx";
let ws = webSocket.createWebSocket();

@Component
export struct Socket {
  @State message: string = 'ContinuousTask';
  // 通过getContext方法,来获取page所在的UIAbility上下文。
  private context: Context = getContext(this);

  aboutToAppear() {
    let wantAgentInfo: wantAgent.WantAgentInfo = {
      // 点击通知后,将要执行的动作列表
      // 添加需要被拉起应用的bundleName和abilityName
      wants: [
        {
          bundleName: "com.example.myapp",
          abilityName: "EntryAbility"
        }
      ],
      // 指定点击通知栏消息后的动作是拉起ability
      actionType: wantAgent.OperationType.START_ABILITY,
      // 使用者自定义的一个私有值
      requestCode: 0,
      // 点击通知后,动作执行属性
      actionFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG]
    };

    try {
      // 通过wantAgent模块下getWantAgent方法获取WantAgent对象
      wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj: WantAgent) => {
        try {
          let list: Array<string> = ["voip"];
          backgroundTaskManager.startBackgroundRunning(this.context, list, wantAgentObj)
            .then((res: backgroundTaskManager.ContinuousTaskNotification) => {
              console.info("Operation startBackgroundRunning succeeded");
              // 此处执行具体的长时任务逻辑,如录音,录制等。
              ws.on('open', (err: BusinessError, value: Object) => {
                console.log("on open, status:" + value);
                // 当收到on('open')事件时,可以通过send()方法与服务器进行通信
                ws.send("Hello, server!", (err: BusinessError, value: boolean) => {
                  if (!err) {
                    console.log("Message send successfully");
                  } else {
                    console.log("Failed to send the message. Err:" + err);
                  }
                });
              });
              ws.on('message', (err: BusinessError, value: string | ArrayBuffer) => {
                console.log("on message, message:" + value);
                // 当收到服务器的`bye`消息时(此消息字段仅为示意,具体字段需要与服务器协商),主动断开连接
                if (value === 'bye') {
                  ws.close((err: BusinessError, value: boolean) => {
                    if (!err) {
                      console.log("Connection closed successfully");
                    } else {
                      console.log("Failed to close the connection. Err:" + err);
                    }
                  });
                }
              });
              ws.on('close', (err: BusinessError, value: webSocket.CloseResult) => {
                console.log("on close, code is " + value.code + ", reason is " + value.reason);
              });
              ws.on('error', (err: BusinessError) => {
                console.log("on error, error:" + err);
              });
              ws.connect(defaultIpAddress, (err: BusinessError, value: boolean) => {
                if (!err) {
                  console.log("Connected successfully");
                } else {
                  console.log("Connection failed. Err:" + err);
                }
              });
            })
            .catch((error: BusinessError) => {
              console.error(`Failed to Operation startBackgroundRunning. code is ${error.code} message is ${error.message}`);
            });
        } catch (error) {
          console.error(`Failed to Operation startBackgroundRunning. code is ${(error as BusinessError).code} message is ${(error as BusinessError).message}`);
        }
      });
    } catch (error) {
      console.error(`Failed to Operation getWantAgent. code is ${(error as BusinessError).code} message is ${(error as BusinessError).message}`);
    }
  }

  build() {
    Button("发送消息").onClick((event: ClickEvent) => {
      ws.send("我发消息了,我是xx")
    })
  }
}

另外,也可以参考示例:弱网情况下的即时通讯,本示例基于[@ohos.net.webSocket](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-websocket)实现弱网情况下使用心跳和重连机制保障通讯。

更多关于HarmonyOS鸿蒙Next中这个库:https://gitcode.com/openharmony-tpc/openharmony_tpc_samples/tree/master/ohos_smack ;目前没有找到保持链接的相关逻辑比如ping或设置keepali的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


该库未实现TCP长连接保持机制。鸿蒙Next中网络连接管理由系统统一调度,应用层通常无需主动发送心跳包。若需维持长连接,建议使用系统提供的Socket或WebSocket API,它们内置了连接状态维护功能。开发者可关注官方文档中关于网络连接生命周期的说明。

在HarmonyOS Next中,ohos_smack库目前确实缺少原生的连接保活机制(如XMPP协议的ping或keepalive)。这通常会导致长时间无数据交互时连接被服务器或网络设备断开。

针对这个问题,你可以通过以下方式实现连接保活:

  1. 应用层定时发送空节(Whitespace Ping): 在XMPP协议中,可以在应用层定时(例如每30秒)向服务器发送一个空格字符()。这是XMPP规范允许的简单保活方式,能有效维持TCP连接。

  2. 自定义Ping逻辑: 在Smack库基础上扩展,定时发送XMPP协议的标准ping请求(<iq type='get' id='...'><ping xmlns='urn:xmpp:ping'/></iq>)。需要处理服务器的ping响应以确保持续连接。

  3. 调整TCP参数(需系统支持): 如果系统提供Socket选项设置,可以尝试设置SO_KEEPALIVE参数来启用TCP层的保活探测。但这取决于HarmonyOS的Socket实现支持程度。

  4. 业务层心跳包: 如果以上协议层方式不可行,可以在业务层设计简单的心跳协议,定时发送特定业务报文维持连接。

建议优先采用第1或第2种方式,这两种是XMPP生态中标准的保活方案。你需要在现有ohos_smack库的基础上,在连接管理类中添加定时任务来发送保活数据。

由于这是开源社区提供的示例库,其功能可能不完整。你可以考虑基于现有代码自行实现保活模块,或向该仓库提交功能需求。

回到顶部