随着 HarmonyOS Next 系统的不断发展与应用拓展,开发高效、稳定的网络通信功能变得愈发重要。WebSocket 作为一种基于 TCP 协议的网络通信协议,能够在客户端和服务器之间实现双向通信,在实时性要求较高的应用场景中有着广泛的应用。本文将介绍如何在HarmonyOS Next 环境下,利用 ArkTs&ArkUI 框架构建 WebSocket 客户端,并搭配 Node.js 搭建的后台服务器来实现简单的消息交互功能,展示完整的代码实现过程及效果。
客户端-ArkTs&ArkUI
配置网络权限
在src下的module.json5里加入权限:
"requestPermissions": [
{ "name": "ohos.permission.INTERNET" },
],
使用ArkTS自带的WebSocket API
import { webSocket } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
创建WebSocket实例
defaultIpAddress: string = 'ws://xx.xx.xx.xx:8080';//后台服务器端口为8080
ws = webSocket.createWebSocket();
处理WebSocket事件
1.open 事件
-
触发时机:连接成功时。
-
回调参数:
err:错误信息,如果没有错误则为null。value:连接成功后的信息对象,通常是空对象或包含一些连接的元数据。
this.ws.on('open', (err: BusinessError, value: Object) => {
if (!err) {
this.addMessage('连接成功!');
} else {
this.addMessage('连接失败:' + JSON.stringify(err));
}
});
2. message 事件
-
触发时机:当收到服务器的消息时。
-
回调参数:
err:错误信息,如果没有错误则为null。value:服务器返回的消息,类型可能是string或ArrayBuffer,表示接收到的消息内容。
this.ws.on('message', (err: BusinessError, value: string | ArrayBuffer) => {
if (!err && typeof value === 'string') {
this.addMessage('服务器: ' + value);
} else {
this.addMessage('接收消息错误: ' + JSON.stringify(err));
}
});
3. close 事件
-
触发时机:当 WebSocket 连接关闭时(无论是正常关闭还是异常关闭)。
-
回调参数:
err:错误信息,如果没有错误则为null。value:关闭连接时的结果,通常包含code和reason,描述关闭的原因和状态码。
this.ws.on('close', (err: BusinessError, value: webSocket.CloseResult) => {
if (!err) {
this.addMessage(`连接关闭,代码: ${value.code}, 原因: ${value.reason}`);
} else {
this.addMessage('关闭连接错误: ' + JSON.stringify(err));
}
});
4. error 事件
-
触发时机:发生 WebSocket 错误时。
-
回调参数:
err:错误信息,描述错误的具体内容。
this.ws.on('error', (err: BusinessError) => {
this.addMessage('WebSocket 错误: ' + JSON.stringify(err));
});
5.connect事件
-
触发时机:客户端主动发起连接。
-
回调参数:
err:错误信息,描述错误的具体内容。value:连接成功的结果,通常包含code和reason,描述结果和状态码。
this.ws.connect(this.defaultIpAddress, (err: BusinessError, value: boolean) => {
if (err) {
this.addMessage('无法连接到服务器: ' + JSON.stringify(err));
}
});
创建UI:
build() {
Row(){
Column() {
List(){
ForEach(this.messages, (item: string) => {
ListItem(){
Text(item)
.fontSize(20)
.padding(10);
}
})
}
.width('100%')
.height('90%');
Row() {
TextInput({
placeholder:"输入消息",
controller:this.controller,
text:this.inputMessage
})
.onChange((value) => {
this.inputMessage = value;
})
.width('70%')
.height(40);
Button("发送")
.onClick(() => {
if (this.inputMessage.trim()) {
this.sendMessage();
}
})
.width('20%')
.height(40)
.margin({ left: 10 });
}
.width('100%')
.height('15%')
.margin({ top: 10 });
}
.padding(10);
}
}
总代码:
import { webSocket } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct Index {
@State messages: string[] = [];
@State inputMessage: string = '';
defaultIpAddress: string = 'ws://10.23.102.19:8080';
ws = webSocket.createWebSocket();
controller: TextInputController = new TextInputController();
build() {
Row(){
Column() {
List(){
ForEach(this.messages, (item: string) => {
ListItem(){
Text(item)
.fontSize(20)
.padding(10);
}
})
}
.width('100%')
.height('90%');
Row() {
TextInput({
placeholder:"输入消息",
controller:this.controller,
text:this.inputMessage
})
.onChange((value) => {
this.inputMessage = value;
})
.width('70%')
.height(40);
Button("发送")
.onClick(() => {
if (this.inputMessage.trim()) {
this.sendMessage();
}
})
.width('20%')
.height(40)
.margin({ left: 10 });
}
.width('100%')
.height('15%')
.margin({ top: 10 });
}
.padding(10);
}
}
aboutToAppear() :void{
this.connectWebSocket();
}
onDisappear() {
this.closeWebSocket();
}
connectWebSocket() {
this.ws.on('open', (err: BusinessError, value: Object) => {
if (!err) {
this.addMessage('连接成功!');
} else {
this.addMessage('连接失败:' + JSON.stringify(err));
}
});
this.ws.on('message', (err: BusinessError, value: string | ArrayBuffer) => {
if (!err && typeof value === 'string') {
this.addMessage('服务器: ' + value);
} else {
this.addMessage('接收消息错误: ' + JSON.stringify(err));
}
});
this.ws.on('close', (err: BusinessError, value: webSocket.CloseResult) => {
if (!err) {
this.addMessage(`连接关闭,代码: ${value.code}, 原因: ${value.reason}`);
} else {
this.addMessage('关闭连接错误: ' + JSON.stringify(err));
}
});
this.ws.on('error', (err: BusinessError) => {
this.addMessage('WebSocket 错误: ' + JSON.stringify(err));
});
this.ws.connect(this.defaultIpAddress, (err: BusinessError, value: boolean) => {
if (err) {
this.addMessage('无法连接到服务器: ' + JSON.stringify(err));
}
});
}
closeWebSocket() {
if (this.ws) {
this.ws.close((err: BusinessError, value: boolean) => {
if (!err) {
this.addMessage('WebSocket 连接已关闭');
} else {
this.addMessage('关闭 WebSocket 失败: ' + JSON.stringify(err));
}
});
}
}
// 发送消息
sendMessage() {
if (this.inputMessage.trim() === '') {
this.addMessage('请先输入消息');
return;
}
const message = this.inputMessage;
this.inputMessage = ''; // 清空输入框
this.ws.send(message, (err: BusinessError, value: boolean) => {
if (!err) {
this.addMessage('我: ' + message);
} else {
this.addMessage('消息发送失败: ' + JSON.stringify(err));
}
});
}
// 添加消息到列表
addMessage(msg: string) {
this.messages = [...this.messages, msg];
}
}
后台创建
用Node.js 快速构建
安装WebSocket模块:
npm install ws
后台代码:
const WebSocket = require('ws');
// 创建一个 WebSocket 服务器
const wss = new WebSocket.Server({ port: 8080 });
console.log('WebSocket 服务器正在运行,监听端口 8080');
// 监听客户端连接
wss.on('connection', (ws) => {
console.log('客户端已连接');
// 监听客户端发送的消息
ws.on('message', (message) => {
console.log(`收到客户端消息: ${message}`);
// 向客户端发送回执消息
ws.send(`服务端收到: ${message}`);
});
// 处理连接关闭
ws.on('close', () => {
console.log('客户端已断开连接');
});
// 处理错误
ws.on('error', (error) => {
console.error(`WebSocket 错误: ${error.message}`);
});
// 发送欢迎消息
ws.send('欢迎连接到 WebSocket 服务器');
});
效果展示: 