HarmonyNext使用TcpSocket实现长连接(三) 原创

zhouchy
发布于 2025-3-8 21:50
浏览
0收藏


 文章目录

概要

在上篇文章中,我们已经对整体架构有了比较详细的了解,本章我将提供一些样例代码供大家参口,如有错误,欢迎指正。

技术细节

实例化TCPSocket

private sockets = socket.constructTCPSocketInstance()
private worker = new worker.ThreadWorker("entry/ets/workers/Worker.ets"));

// 已连接
socket.on('connect', () => {
  
});
// 断开连接
socket.on('close', data {
  
});
// 接收数据
socket.on('message', value {
  let byteArray = new Uint8Array(value.message);
  this.worker.postMessage(byteArray);
});
// 连接异常
socket.on('error', err {
  
});
// 绑定服务器ip 端口
socket.bind({ address: server.ip, port: server.port, family: 1 }).then(() => {
  
}).catch((err: BusinessError) => {
  
});
// 创建连接
socket.connect({
  address: { address: server.ip, port: server.port, family: 1 }, timeout: 2000
}).then(() => {
  let promiseExtraOptions = socket.setExtraOptions({
    keepAlive: true,
    OOBInline: true,
    TCPNoDelay: true,
    socketLinger: {
      on: true, linger: 10
    },
    reuseAddress: true,
    receiveBufferSize: 1024 * 1024,
    sendBufferSize: 1024 * 1024
  });
  promiseExtraOptions.then(() => {
    
  }).catch((err: BusinessError) => {
    
  })
}).catch((err: BusinessError) => {
    
})

定义Worker

let workerPort : ThreadWorkerGlobalScope = worker.workerPort;

/**
 * Defines the event handler to be called when the worker thread receives a message sent by the host thread.
 * The event handler is executed in the worker thread.
 *
 * @param

const bufferCache: buffer.Buffer = buffer.from([])

workerPort.onmessage = async (e: MessageEvents) => {
  let byteArray = e.data as Uint8Array;
  let byteBuffer = buffer.from(byteArray);

  bufferCache = buffer.concat([bufferCache, byteBuffer]);

  try {
    let byteArrayBuffer = bufferCache.buffer;
    if (byteArrayBuffer.byteLength == 0) {
      return;
    }
	// 解析报文头
    let protoResponse: ProtoResponse = await parser.decodePackage(byteArrayBuffer);
    // 如果出现拆包问题,则先缓存数据,接收到剩余数据后再做解析
    if (protoManager.packageHeadLength + protoResponse.bodyLength > protoResponse.packageBuffer.length) {
      return;
    }
	// 将完整报文从缓存数据中移除
    let sliceByteBuffer = bufferCache.subarray(protoManager.packageHeadLength + protoResponse.bodyLength);
    bufferCache = sliceByteBuffer

	// 解析完整报文
    if (protoResponse.bodyArrayBuffer) {
      let task = new taskpool.Task(decodePackageBody, protoResponse.bodyArrayBuffer);
      let decodePackageBodyResult = await taskpool.execute(task) as ProtoResponse;
      
      workerPort.postMessage(decodePackageBodyResult);
    }
  } catch (error) {
    hilog.error(0x0000, TAG, error.message)
  }
}

/**
 * Defines the event handler to be called when the worker receives a message that cannot be deserialized.
 * The event handler is executed in the worker thread.
 *
 * @param
workerPort.onmessageerror = (e: MessageEvents) => {
}

/**
 * Defines the event handler to be called when an exception occurs during worker execution.
 * The event handler is executed in the worker thread.
 *
 * @param
workerPort.onerror = (e: ErrorEvent) => {
}


@Concurrent
async function decodePackageBody(arrayBuffer: ArrayBuffer) {
  // 对报文体进行解析
  return response
}

小结

本章为大家展示了核心的样例代码,希望能给有需要的人带来一些帮助。


©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2025-3-14 20:52:49修改
收藏
回复
举报
回复
    相关推荐