
??想了解更多關于開源的內容,請訪問:??
??51CTO 開源基礎軟件社區??
??https://ost.51cto.com??
WebSocket是一種網絡通訊協議,很多網絡開發工作者都需要它。本文介紹在OpenHarmony上WebSocket協議的使用方法。
WebSocket有什么不同
很多人會問,有了HTTP協議,尤其是RESTFul接口,為什么還需要使用WebSocket?它能帶來什么好處呢?那是因為HTTP協議有一個缺陷,通訊只能由客戶端發起。簡單舉例,我們的天氣應用程序需要查詢天氣就需要客戶端向服務器請求數據,服務器查詢后返回結果。但是如果天氣有變化,客戶端是無法收到服務端推送過來的消息,所以只能定時調用或者用戶手動刷新。
這種單向請求導致需要雙向通訊的應用只能在客戶端采用輪詢的手段來實現,引申出來的問題就是效率低,服務端負載大。所以就誕生了WebSocket。
WebSocket簡介
WebSocket協議誕生于2008年,2011年成為國際標準,所有瀏覽器都支持。它最大的特點就是雙向平等對話,屬于服務器推送技術的一種。


特點:
- 在TCP協議上層,服務器端的實現比較容易。
- 與HTTP協議有著良好的兼容性。默認端口也是80和443,并且握手階段采用 HTTP 協議,因此握手時不容易屏蔽,能通過各種 HTTP 代理服務器。
- 數據格式比較輕量,性能開銷小,通信高效。
- 可發送文本,也可發送二進制數據。
- 沒有同源限制,客戶端可以與任意服務器通信。
- 協議標識符是ws(如果加密,則為wss),服務器網址就是URL。

WebSocket在OpenHarmony上的實現

WebSocket在OpenHarmony上的使用
- 導入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;
- 基本的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<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);
- 異步執行動作。
//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);
}
- 執行結果日志打印。
//正確連接
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??