鸿蒙ETS中WebSocket使用说明
一、WebSocket简介
WebSocket是一种在单个TCP连接上进行全双工通信的协议,允许服务器和客户端之间进行实时数据交换。在鸿蒙ETS(Extended TypeScript)应用中,WebSocket可用于实现实时聊天、实时通知、在线游戏等功能。
二、环境要求
DevEco Studio 3.0或以上版本
API Version 9或以上
需要网络权限
三、使用步骤
1. 添加权限配置
在module.json5文件中添加网络权限:
json
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
}
}
2. 导入WebSocket模块
typescript
import { webSocket } from '@kit.NetworkKit';
3. 创建WebSocket连接
c
typescript
// 创建WebSocket对象
let ws = webSocket.createWebSocket();
// 服务器地址
let url = 'ws://example.com/socket'; // 或 wss:// 用于安全连接
// 可选:设置请求头
let header = {
'Content-Type': 'application/json'
};
// 建立连接
ws.connect(url, header, (err, value) => {
if (err) {
console.error('WebSocket连接失败: ' + JSON.stringify(err));
return;
}
console.log('WebSocket连接成功');
});
4. 监听事件
c
typescript
// 监听连接打开事件
ws.on('open', (err, value) => {
if (err) {
console.error('连接打开失败: ' + JSON.stringify(err));
return;
}
console.log('连接已打开');
});
// 监听消息接收事件
ws.on('message', (err, value) => {
if (err) {
console.error('消息接收错误: ' + JSON.stringify(err));
return;
}
console.log('收到消息: ' + value);
// 处理接收到的数据
this.handleMessage(value);
});
// 监听连接关闭事件
ws.on('close', (err, value) => {
if (err) {
console.error('连接关闭错误: ' + JSON.stringify(err));
return;
}
console.log('连接已关闭,code: ' + value.code + ', reason: ' + value.reason);
});
// 监听错误事件
ws.on('error', (err) => {
console.error('WebSocket错误: ' + JSON.stringify(err));
});
5. 发送数据
c
typescript
// 发送字符串数据
ws.send('Hello Server!', (err, value) => {
if (err) {
console.error('发送消息失败: ' + JSON.stringify(err));
return;
}
console.log('消息发送成功');
});
// 发送JSON数据
let data = {
type: 'message',
content: 'Hello',
timestamp: Date.now()
};
ws.send(JSON.stringify(data), (err, value) => {
if (err) {
console.error('发送JSON失败: ' + JSON.stringify(err));
return;
}
console.log('JSON发送成功');
});
// 发送ArrayBuffer
let arrayBuffer = new ArrayBuffer(8);
let dataView = new DataView(arrayBuffer);
dataView.setInt32(0, 123, false);
dataView.setInt32(4, 456, false);
ws.send(arrayBuffer, (err, value) => {
if (err) {
console.error('发送ArrayBuffer失败: ' + JSON.stringify(err));
return;
}
console.log('ArrayBuffer发送成功');
});
6. 关闭连接
c
typescript
// 正常关闭
ws.close((err, value) => {
if (err) {
console.error('关闭连接失败: ' + JSON.stringify(err));
return;
}
console.log('连接已关闭');
});
// 带状态码和原因关闭
ws.close({
code: 1000,
reason: 'Normal closure'
}, (err, value) => {
if (err) {
console.error('关闭连接失败: ' + JSON.stringify(err));
return;
}
console.log('连接已关闭');
});
四、完整示例
c
typescript
import { webSocket } from '@kit.NetworkKit';
@Entry
@Component
struct WebSocketExample {
@State message: string = '';
@State receivedMessages: string[] = [];
private ws: webSocket.WebSocket = webSocket.createWebSocket();
private url: string = 'ws://your-websocket-server.com/ws';
build() {
Column({ space: 10 }) {
Text('WebSocket示例')
.fontSize(20)
.fontWeight(FontWeight.Bold)
TextInput({ placeholder: '输入要发送的消息' })
.width('90%')
.onChange((value: string) => {
this.message = value;
})
Button('连接WebSocket')
.width('90%')
.onClick(() => {
this.connectWebSocket();
})
Button('发送消息')
.width('90%')
.onClick(() => {
this.sendMessage();
})
Button('断开连接')
.width('90%')
.onClick(() => {
this.disconnectWebSocket();
})
List({ space: 10 }) {
ForEach(this.receivedMessages, (item: string, index: number) => {
ListItem() {
Text(item)
.fontSize(14)
.padding(10)
}
}, (item: string, index: number) => index.toString())
}
.height('40%')
.width('90%')
.divider({ strokeWidth: 1, color: '#CCCCCC' })
}
.width('100%')
.height('100%')
.padding(10)
}
// 连接WebSocket
connectWebSocket() {
// 设置事件监听
this.setupEventListeners();
// 建立连接
this.ws.connect(this.url, {}, (err, value) => {
if (err) {
console.error('连接失败: ' + JSON.stringify(err));
prompt.showToast({
message: '连接失败',
duration: 2000
});
return;
}
console.log('连接成功');
prompt.showToast({
message: '连接成功',
duration: 2000
});
});
}
// 设置事件监听器
setupEventListeners() {
// 连接打开
this.ws.on('open', () => {
console.log('WebSocket连接已打开');
});
// 接收消息
this.ws.on('message', (err, value) => {
if (err) {
console.error('接收消息错误: ' + JSON.stringify(err));
return;
}
console.log('收到消息: ' + value);
this.receivedMessages.unshift(`[${new Date().toLocaleTimeString()}] ${value}`);
});
// 连接关闭
this.ws.on('close', (err, value) => {
if (err) {
console.error('关闭错误: ' + JSON.stringify(err));
return;
}
console.log('连接关闭');
prompt.showToast({
message: '连接已断开',
duration: 2000
});
});
// 错误处理
this.ws.on('error', (err) => {
console.error('WebSocket错误: ' + JSON.stringify(err));
prompt.showToast({
message: '连接错误',
duration: 2000
});
});
}
// 发送消息
sendMessage() {
if (!this.message.trim()) {
prompt.showToast({
message: '请输入消息',
duration: 2000
});
return;
}
this.ws.send(this.message, (err, value) => {
if (err) {
console.error('发送失败: ' + JSON.stringify(err));
prompt.showToast({
message: '发送失败',
duration: 2000
});
return;
}
console.log('发送成功: ' + this.message);
this.receivedMessages.unshift(`[发送] ${this.message}`);
this.message = '';
});
}
// 断开连接
disconnectWebSocket() {
this.ws.close((err, value) => {
if (err) {
console.error('断开连接失败: ' + JSON.stringify(err));
return;
}
console.log('已断开连接');
});
}
// 页面销毁时关闭连接
aboutToDisappear() {
this.disconnectWebSocket();
}
}
五、心跳检测机制
c
typescript
private heartbeatInterval: number = 0;
// 开始心跳检测
startHeartbeat() {
this.heartbeatInterval = setInterval(() => {
if (this.ws) {
this.ws.send('ping', (err, value) => {
if (err) {
console.error('心跳发送失败');
this.reconnect();
}
});
}
}, 30000); // 每30秒发送一次心跳
}
// 停止心跳检测
stopHeartbeat() {
if (this.heartbeatInterval) {
clearInterval(this.heartbeatInterval);
this.heartbeatInterval = 0;
}
}
// 重连机制
private reconnectAttempts: number = 0;
private maxReconnectAttempts: number = 5;
reconnect() {
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
console.error('达到最大重连次数');
return;
}
this.reconnectAttempts++;
setTimeout(() => {
console.log(`尝试重连,第${this.reconnectAttempts}次`);
this.connectWebSocket();
}, 2000 * this.reconnectAttempts); // 指数退避
}
六、注意事项
网络权限:确保已添加正确的网络权限
URL协议:使用ws://(非加密)或wss://(加密)
生命周期管理:在页面销毁时关闭连接,避免内存泄漏
错误处理:做好网络异常和服务器异常的处理
数据类型:注意发送和接收的数据类型
线程安全:WebSocket操作应在主线程中进行
七、常见问题
Q1: 连接失败
检查网络权限配置
确认服务器地址和端口正确
检查服务器是否支持WebSocket协议
Q2: 消息发送失败
检查连接状态是否正常
确认发送的数据格式正确
检查服务器端是否正常处理
Q3: 频繁断开
实现心跳机制保持连接
添加自动重连功能
检查网络稳定性
八、最佳实践
封装WebSocket工具类,统一管理连接状态
添加消息队列机制,确保消息顺序
实现重连策略,增强连接稳定性
添加消息类型管理,便于处理不同类型的数据
使用JSON格式进行数据交换,便于扩展
通过以上说明,您可以在鸿蒙ETS应用中成功集成和使用WebSocket功能,实现实时通信需求。