NativeScript 默认不支持 WebSocket,但你可以使用第三方插件轻松地将其添加到你的项目中。在本文中,我将指导你如何利用这个神奇的 WebSocket 作为高效的通信通道,并在你的 NativeScript Vue 应用中探索更多实际用例。
WebSocket 是一种双向、全双工协议,在客户端(如浏览器)和服务器之间建立一个持久的、低延迟的连接。一旦建立连接,双方都可以即时发送数据——无需等待请求或页面刷新。它就像打电话,而无休止的短信则不然。
安装包 @valor/nativescript-websockets
有许多可用于 NativeScript 连接 WebSocket 的插件,我个人最喜欢的是 @valor/nativescript-websockets。这个包的优点在于它不会让你导入任何额外的类。它实际上将 WebSocket 类填充(polyfill)到你的项目中,让你可以像在 Web 环境中一样使用它。
要安装这个很棒的包,请使用如下 npm 命令:
npm i --save @valor/nativescript-websockets
连接到 WebSocket 并发送消息
如果你已经熟悉在 Web 环境中使用 WebSocket,那么这一步应该很简单,因为 Web 和 NativeScript 的 API 是相同的。
不过,如果你不熟悉,不用担心。我将引导你了解在 NativeScript 中 WebSocket 的基本用法。首先,我们需要使用以下方式创建一个 WebSocket 实例:
let ws = new WebSocket('wss://echo.websocket.org/');
echo.websocket.org 是一个免费的公共 WebSocket 服务器,它会把你发送给它的任何东西原样返回,使其成为本文目的的理想测试目标。
创建 WebSocket 实例后,请务必设置一些基本的事件监听器,这样你就能了解 WebSocket 连接的状态:
ws.onopen = () => {
console.log('WebSocket is open');
};
ws.onmessage = (event: MessageEvent) => {
console.log('WebSocket message received:', event.data);
};
ws.onerror = (event: Event) => {
console.log('WebSocket error:', event);
};
解释:
onopen:WebSocket 连接建立后立即触发此事件。onmessage:每当从 WebSocket 服务器收到消息时发生此事件。onerror:每当连接期间发生错误时(例如连接关闭或传输错误),此事件会提供详细信息。监视错误并相应地调整你的 UI/UX 是一个好主意。
除了使用 ws.onmessage,如果你计划向此 WebSocket 实例添加多个监听器,可以使用 ws.addEventListener("message")。
现在我们有了处理传入消息的方法,但我们仍然需要一种方法从我们的应用向目标 WebSocket 发送消息。要做到这一点,只需调用:
ws.send("Your message");
在上面的调用中,我们的应用会向目标 WebSocket 服务器发送一条纯文本消息。如果你好奇的话,除了文本,我们还可以发送形式为 ArrayBuffer、ArrayBufferView 或 Blob 的二进制数据。如果你好奇的话,下面是底层 send() 接口的样子:
源代码:github.com/valor-softw…
以上是我对 WebSocket API 的简要速成课程。有关详细指南,Mozilla 团队的文档做得非常出色。如果你想了解更多关于 WebSocket API 的信息,请查看他们的指南:Mozilla WebSocket API 指南。
一些注意事项
以下是我遇到过的一些让我挠头的问题。我认为应该分享出来,以帮助其他人避免同样的错误。
WebSocket 和 Vue 的响应式不太合拍
避免使用 ref 来持有 WebSocket 实例。如果你尝试在 ref 变量上调用 send(),会发生一些不期望的事情,导致你的应用立即崩溃,并出现以下消息:
[Vue warn]: Unhandled error during execution of native event handler
at <Home>
***** Fatal JavaScript exception - application has been terminated. *****
NativeScript encountered a fatal error:
Uncaught Error: +[RCTSRWebSocket send:]: unrecognized selector sent to class 0x1086e87c8
at
send(file: src/webpack:/nativescript-websockets/node_modules/@valor/nativescript-websockets/bridge.ios.js:81:0)
at send(file: src/webpack:/nativescript-websockets/node_modules/@valor/nativescript-websockets/websocket.js:139:0)
我尝试调查了这个问题,据我所知,Vue 的响应式似乎在某处干扰了 send() 方法。所以,最好避免这样做。只需将你的 WebSocket 变量声明为普通变量即可:
let ws = new WebSocket(...);
如果需要发送大量二进制数据,请使用 Worker API
如前所述,ws.send() 也可以接受形式为 ArrayBuffer 或 Blob 的二进制数据。如果你计划通过 WebSocket 读取、发送和接收大量的二进制数据,我建议使用 Worker API,如这里所述:NativeScript 多线程指南。
由于 WebSocket 的实时性,你不希望你的主线程因发送和接收数据而陷入困境。
示例消息发送和接收项目
代码胜过千言万语。这里是一个示例聊天 UI,连接并向上述回显 WebSocket 服务器发送消息,供你测试。
GitHub:github.com/NewbieScrip…
结论
与传统的 HTTP 请求相比,WebSocket 提供了一种与你的后端进行实时通信的更高效方式。我希望本文能帮助你将这项神奇的技术集成到你的应用中,从而顺畅地提升用户体验。