鸿蒙上WebSocket的使用方法

描述

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

WebSocket 有什么不同

很多人会问,有了 HTTP 协议,尤其是 RESTFul 接口,为什么还需要使用 WebSocket?它能带来什么好处呢?那是因为 HTTP 协议有一个缺陷,通讯只能由客户端发起。

简单举例,我们的天气应用程序需要查询天气就需要客户端向服务器请求数据,服务器查询后返回结果。

但是如果天气有变化,客户端是无法收到服务端推送过来的消息,所以只能定时调用或者用户手动刷新。

这种单向请求导致需要双向通讯的应用只能在客户端采用轮询的手段来实现,引申出来的问题就是效率低,服务端负载大。所以就诞生了 WebSocket。

WebSocket 简介

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

HTTP 流程:

WebSocket

WebSocket 流程:

WebSocket

特点:

在 TCP 协议上层,服务器端的实现比较容易。

与 HTTP 协议有着良好的兼容性。默认端口也是 80 和 443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。

数据格式比较轻量,性能开销小,通信高效。

可发送文本,也可发送二进制数据。

没有同源限制,客户端可以与任意服务器通信。

协议标识符是 ws(如果加密,则为 wss),服务器网址就是 URL。

WebSocket

WebSocket在OpenHarmony上的实现

    如下图:

WebSocket

WebSocket在OpenHarmony上的使用

      导入 d.ts 文件:

//导入websocket接口
import webSocket from '@ohos.net.webSocket'
//websocket的基本接口函数
connect(url: string, callback: AsyncCallback): void;
send(data: string | ArrayBuffer, callback: AsyncCallback): void;
close(callback: AsyncCallback): void;
基本的 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 层的实现

    Napi 接口实现:

//foundation/communication/netstack/frameworks/js/napi/websocket/websocket_module/src/websocket_module.cpp
std::initializer_list 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);
异步执行动作:
//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(env, data);
}

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

void WebSocketAsyncWork::ExecClose(napi_env env, void *data)
{
    BaseAsyncWork::ExecAsyncWork(env, data);
}
执行结果日志打印:
//正确连接
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 调用,通过回调函数返回调用结果。

作者:王石

 

  审核编辑:汤梓红
 
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分