首页 > 其他分享 > #跟着小白一起学鸿蒙#WebSocket的使用和流程分析

#跟着小白一起学鸿蒙#WebSocket的使用和流程分析

时间:2023-02-27 20:01:01浏览次数:79  
标签:websocket 鸿蒙 NetMgrSubsystem C015b0 小白 NETSTACK cpp WebSocket

作者:王石

WebSocket是一种网络通讯协议,很多网络开发工作者都需要它。本文介绍在OpenHarmony上WebSocket协议的使用方法。

WebSocket有什么不同

很多人会问,有了HTTP协议,尤其是RESTFul接口,为什么还需要使用WebSocket?它能带来什么好处呢?那是因为HTTP协议有一个缺陷,通讯只能由客户端发起。简单举例,我们的天气应用程序需要查询天气就需要客户端向服务器请求数据,服务器查询后返回结果。但是如果天气有变化,客户端是无法收到服务端推送过来的消息,所以只能定时调用或者用户手动刷新。 这种单向请求导致需要双向通讯的应用只能在客户端采用轮询的手段来实现,引申出来的问题就是效率低,服务端负载大。所以就诞生了WebSocket。

WebSocket简介

WebSocket协议诞生于2008年,2011年成为国际标准,所有浏览器都支持。它最大的特点就是双向平等对话,属于服务器推送技术的一种。

  • HTTP流程
Client -->> Server: request
Server -->> Client: response
  • WebSocket流程
Client -->> Server: handshake
Server -->> Client: acknowledgement
Client -->> Server: bi-directional messages
Server-->> Client : bi-directional messages
Client -->> Server: connection end

特点:

  1. 在TCP协议上层,服务器端的实现比较容易。
  2. 与HTTP协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
  3. 数据格式比较轻量,性能开销小,通信高效。
  4. 可发送文本,也可发送二进制数据。
  5. 没有同源限制,客户端可以与任意服务器通信。
  6. 协议标识符是ws(如果加密,则为wss),服务器网址就是URL。 图片.png

WebSocket在OpenHarmony上的实现

JS -->> Framework: Napi调用
Framework-->> Libwebsockets: 静态库接口调用

WebSocket在OpenHarmony上的使用

  1. 导入d.ts文件
//导入websocket接口
import webSocket from '@ohos.net.webSocket'
//websocket的基本接口函数
connect(url: string, callback: AsyncCallback<boolean>): void;
send(data: string | ArrayBuffer, callback: AsyncCallback<boolean>): void;
close(callback: AsyncCallback<boolean>): void;
  1. 基本的websocket流程
    let promise = socket.connect(url)
    promise.then((value) => {
      Logger.info(TAG, `connect success`)
    }).catch((err) => {
      Logger.info(TAG, `connect fail, error:${JSON.stringify(err)}`)
    })
    socket.on('open', (err, value) => {
      prompt.showToast({ message: '连接成功', duration: 1500 })
    })
    socket.on('message', (err, value) => {
      Logger.info(TAG, `on message, value = ${value}`)
    })

Framework层的实现

  1. Napi接口实现
//foundation/communication/netstack/frameworks/js/napi/websocket/websocket_module/src/websocket_module.cpp
std::initializer_list<napi_property_descriptor> properties = {
    DECLARE_NAPI_FUNCTION(WebSocket::FUNCTION_CONNECT, WebSocket::Connect),
    DECLARE_NAPI_FUNCTION(WebSocket::FUNCTION_SEND, WebSocket::Send),
    DECLARE_NAPI_FUNCTION(WebSocket::FUNCTION_CLOSE, WebSocket::Close),
    DECLARE_NAPI_FUNCTION(WebSocket::FUNCTION_ON, WebSocket::On),
    DECLARE_NAPI_FUNCTION(WebSocket::FUNCTION_OFF, WebSocket::Off),
};
ModuleTemplate::DefineClass(env, exports, properties, INTERFACE_WEB_SOCKET);
  1. 异步执行动作
//foundation/communication/netstack/frameworks/js/napi/websocket/async_work/src/websocket_async_work.cpp
//初始化libwebsocket需要的callback
static const lws_protocols LWS_PROTOCOLS[] = {
    {"lws-minimal-client", WebSocketExec::LwsCallback, 0, 0},
    {nullptr, nullptr, 0, 0}, // this line is needed
};

//填装websocket上下文信息
static inline void FillContextInfo(lws_context_creation_info &info)
{
    info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
    info.port = CONTEXT_PORT_NO_LISTEN;
    info.protocols = LWS_PROTOCOLS;
    info.fd_limit_per_thread = FD_LIMIT_PER_THREAD;
}

void WebSocketAsyncWork::ExecConnect(napi_env env, void *data)
{
    BaseAsyncWork::ExecAsyncWork<ConnectContext, WebSocketExec::ExecConnect>(env, data);
}

void WebSocketAsyncWork::ExecSend(napi_env env, void *data)
{
    BaseAsyncWork::ExecAsyncWork<SendContext, WebSocketExec::ExecSend>(env, data);
}

void WebSocketAsyncWork::ExecClose(napi_env env, void *data)
{
    BaseAsyncWork::ExecAsyncWork<CloseContext, WebSocketExec::ExecClose>(env, data);
}
  1. 执行结果日志打印
//正确连接
I C015b0/NetMgrSubsystem: NETSTACK [connect_context.cpp 43] ConnectContext NapiUtils::GetValueType(GetEnv(), params[1]) == napi_function
I C015b0/NetMgrSubsystem: NETSTACK [module_template.h 61] js params parse OK ? 1
I C015b0/NetMgrSubsystem: NETSTACK [websocket_exec.cpp 471] begin connect, parse url
E C015b0/NetsysNativeService: [HookSocket-(netsys_sock_client.cpp:45)]musl create socket failed
I C015b0/NetMgrSubsystem: NETSTACK [websocket_exec.cpp 228] start service
I C015b0/NetMgrSubsystem: NETSTACK [websocket_exec.cpp 533] ConnectCallback connect success

//错误连接
I C015b0/NetMgrSubsystem: NETSTACK [connect_context.cpp 43] ConnectContext NapiUtils::GetValueType(GetEnv(), params[1]) == napi_function
I C015b0/NetMgrSubsystem: NETSTACK [module_template.h 61] js params parse OK ? 1
I C015b0/NetMgrSubsystem: NETSTACK [websocket_exec.cpp 471] begin connect, parse url
E C015b0/NetsysNativeService: [HookSocket-(netsys_sock_client.cpp:45)]musl create socket failed
I C015b0/NetMgrSubsystem: NETSTACK [websocket_exec.cpp 358] LwsCallbackClientConnectionError DNS NXDOMAIN
I C015b0/NetMgrSubsystem: NETSTACK [websocket_exec.cpp 427] LwsCallbackWsiDestroy
I C015b0/NetMgrSubsystem: NETSTACK [websocket_exec.cpp 515] ExecConnect websocket connect failed
I C015b0/NetMgrSubsystem: NETSTACK [websocket_exec.cpp 433] LwsCallbackProtocolDestroy
I C015b0/NetMgrSubsystem: NETSTACK [websocket_exec.cpp 530] ConnectCallback connect failed

小结

OpenHarmony目前已支持WebSocket调用,通过回调函数返回调用结果。

本文作者:左翼风发

想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com/#bkwz​

标签:websocket,鸿蒙,NetMgrSubsystem,C015b0,小白,NETSTACK,cpp,WebSocket
From: https://blog.51cto.com/harmonyos/6088146

相关文章

  • nginx反向代理WebSocket
    1.nginx反向代理websocket原理2.nginx配置文件详解2.1map值映射2.2upstream2.3location3.nginx反向代理协议升级======================================......
  • 小白成神day5
    顺序结构java的基本结构就是顺序结构,除非特别指明,否则就按照顺序逐句执行顺序结构是最简单的算法结构语句与语句之间,框与框之间是按从上到下的顺序进行的,他是由若干个......
  • websocket报错集锦-不断更新中
    问题1:Failedtoconstruct'WebSocket':AninsecureWebSocketconnectionmaynotbeinitiatedfromapageloadedoverHTTPS.问题描述MixedContent:Thepageat......
  • 小白成神day4
    用户交互Scannerscanner对象来获取用户的输入Scanners=newScanner(System.in);通过Scanner类的next()与nextLine()方法来获取输入的字符串,在读取之前一般使用hasN......
  • HTML5的WebSocket使用
    index.html(客户端)1<!DOCTYPEhtml>2<htmllang="en">3<head>4<metacharset="UTF-8"/>5<metaname="viewport"content="width=device-width......
  • 牛客小白月赛67
    比赛链接很久没有打比赛了,这次刚好看到了牛客的月赛,就做了一下。只会前四题,难度不大。一、画牌河思路:直接按照题目要求输出一个矩阵即可,前x个元素为1,后面元素为0代码:......
  • 小白成神day3
    变量每个变量都必须声明其类型。java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。每个变量都有类型,类型可以是基本类型,也可以是引用类型。变量名......
  • websocket接口自动化集成pytest测试框架
    每天进步一点点,关注我们哦,每天分享测试技术文章本文章出自【码同学软件测试】码同学公众号:自动化软件测试,领取资料可加:magetest码同学抖音号:小码哥聊软件测试 01web......
  • 【小白】FileZilla Window安装并连接 Centos7
    本文是小白教程 通过 FileZilla来实现 windows系统到Centos7 服务器的文件传输。FTP概述文件传输协议(FileTransferProtocol,FTP)是用于在网络上进行文......
  • C#websocket及时通信协议的实现方法示例
    传统“长轮询”实现Web端即时通讯的问题WebSocket出现之前,Web端为了实现即时通讯,所用的技术都是Ajax轮询(polling)。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发......