HarmonyOS WebSocket全场景应用开发深度解析

news/2025/4/2 1:37:27/

注:适用版本(Harmony OS NEXT / 5.0 / API 12+ )

一、最终效果预览

                                                

二、基础代码结构

@Entry
@Component
struct ChatApp {@State messages: Message[] = []  // 所有聊天记录@State inputText: string = ""    // 输入框内容@State isConnected: boolean = false // 是否在线private ws: webSocket.WebSocket | null = null// 建立连接private connect() {this.ws = webSocket.createWebSocket()this.ws.connect('wss://toolin.cn/echo')// 四个关键监听this.ws.on('open', () => this.isConnected = true)this.ws.on('message', (data) => {this.messages = [...this.messages, new Message('received', data.message)]})this.ws.on('close', () => this.isConnected = false)this.ws.on('error', (err) => console.error('出错啦:', err))}// 发送消息private sendMessage() {if (this.inputText && this.isConnected) {this.ws?.send(this.inputText)this.messages = [...this.messages, new Message('sent', this.inputText)]this.inputText = ""}}build() { /* 界面代码 */ }
}

三、核心功能

        1、连接状态管理
// 显示连接状态
Text(this.isConnected ? '🟢 在线' : '🔴 离线').fontColor(this.isConnected ? Color.Green : Color.Red)// 连接/断开按钮
Button(this.isConnected ? '断开连接' : '点击连接').onClick(() => {this.isConnected ? this.ws?.close() : this.connect()})
        2、消息收发演示
// 消息输入框
TextInput({ text: this.inputText, placeholder: '说点什么...'}).onChange((text) => this.inputText = text)// 发送按钮
Button('发送').onClick(() => this.sendMessage())// 消息气泡样式
List() {ForEach(this.messages, (msg) => {ListItem() {Text(`${msg.type === 'sent' ? '我' : '对方'}: ${msg.content}`).backgroundColor(msg.type === 'sent' ? '#e3f2fd' : '#ffffff').padding(10).borderRadius(8)}})
}

        3、自动重连机制(心跳机制)

// 简单重连逻辑
private reconnect() {setTimeout(() => {console.log('尝试重新连接...')this.connect()}, 3000) // 3秒后重试
}// 在连接断开时触发
this.ws.on('close', () => {this.isConnected = falsethis.reconnect() // 自动重连
})

 四、源码详情

import webSocket from '@ohos.net.webSocket' // 导入 WebSocket 模块
import { promptAction } from '@kit.ArkUI' // 导入弹窗模块export class Message { // 定义消息类type: 'sent' | 'received' // 消息类型,发送或接收content: string // 消息内容timestamp: number // 消息时间戳constructor(type: 'sent' | 'received', content: string) { // 构造函数this.type = type // 设置消息类型this.content = content // 设置消息内容this.timestamp = new Date().getTime() // 设置当前时间戳}
}@Entry // 标记为入口组件
@Component // 标记为组件
struct WebSocketDemo { // 定义 WebSocketDemo 组件// WebSocket 连接状态@State isConnected: boolean = false // 初始化为未连接// 消息输入框内容@State inputMessage: string = '' // 初始化为空字符串// 消息记录列表@State messages: Message[] = [] // 初始化为空数组// WebSocket 对象private ws: webSocket.WebSocket | null = null // 初始化为 null// 初始化 WebSocketprivate initWebSocket() {const wsUrl = 'wss://toolin.cn/echo' // 使用公共测试服务器try {this.ws = webSocket.createWebSocket() // 创建 WebSocket 实例// 注册事件监听this.ws.on('open', () => { // 监听连接打开事件this.isConnected = true // 设置连接状态为已连接this.addMessage('received', '连接已建立') // 添加连接成功消息})this.ws.on('message', (data) => { // 监听消息事件// 检查 data 对象是否包含 message 属性if (data && data.message) {this.addMessage('received', `收到消息: ${data.message}`) // 添加收到的消息} else {console.error('Received unexpected data:', data) // 输出错误日志}})this.ws.on('close', () => { // 监听连接关闭事件this.isConnected = false // 设置连接状态为未连接this.addMessage('received', '连接已关闭') // 添加连接关闭消息})this.ws.on('error', (err: Error) => { // 监听错误事件console.error('WebSocket 错误:', err) // 输出错误日志this.showAlert(`错误: ${err.message}`) // 显示错误弹窗})// 发起连接this.ws.connect(wsUrl) // 连接到 WebSocket 服务器} catch (error) {this.showAlert(`初始化失败: ${error.message}`) // 显示初始化失败弹窗}}// 添加消息到列表private addMessage(type: 'sent' | 'received', content: string) {this.messages = [...this.messages, new Message(type, content)] // 将新消息添加到消息列表}// 显示弹窗private async showAlert(message: string) {const res = await promptAction.showDialog({ // 显示弹窗title: '提示', // 弹窗标题message: message, // 弹窗内容buttons: [ // 弹窗按钮{ text: '取消', color: '#999999' }, // 取消按钮{ text: '确定', color: '#007aff' } // 确定按钮]})}build() {Column() { // 垂直布局// 连接状态显示Text(this.isConnected ? '已连接' : '未连接') // 显示连接状态.fontColor(this.isConnected ? Color.Green : Color.Red) // 设置字体颜色.margin(10) // 设置外边距// 控制按钮Row() { // 水平布局Button(this.isConnected ? '断开连接' : '建立连接') // 根据连接状态显示按钮文本.onClick(() => { // 点击事件处理if (this.isConnected) {this.ws?.close() // 关闭 WebSocket 连接this.ws = null // 将 WebSocket 对象设置为 null} else {this.initWebSocket() // 初始化 WebSocket 连接}}).margin(5) // 设置外边距Button('清空记录') // 清空记录按钮.onClick(() => this.messages = []) // 清空消息列表.margin(5) // 设置外边距}// 消息输入区TextInput({ text: this.inputMessage,placeholder:'请输入消息'}) // 文本输入框.onChange((value: string) => this.inputMessage = value) // 输入内容变化时更新 inputMessage.margin(10) // 设置外边距.height(60) // 设置高度.width('90%') // 设置宽度Button('发送消息') // 发送消息按钮.onClick(() => { // 点击事件处理if (this.inputMessage.trim() && this.isConnected) { // 检查输入内容和连接状态this.ws?.send(this.inputMessage) // 发送消息this.addMessage('sent', this.inputMessage) // 添加发送的消息this.inputMessage = '' // 清空输入框}}).margin(10) // 设置外边距// 消息记录列表List({ space: 10 }) { // 列表布局ForEach(this.messages, (msg: Message) => { // 遍历消息列表ListItem() { // 列表项Column() { // 垂直布局Text(`${msg.type === 'sent' ? '[发送]' : '[接收]'} ${msg.content}`) // 显示消息类型和内容.fontSize(14) // 设置字体大小.fontColor(msg.type === 'sent' ? Color.Blue : Color.Gray) // 设置字体颜色Text(new Date(msg.timestamp).toLocaleTimeString()) // 显示消息时间.fontSize(10) // 设置字体大小.fontColor(Color.Gray) // 设置字体颜色}.padding(10) // 设置内边距.width('100%') // 设置宽度.alignItems(msg.type === 'sent' ? HorizontalAlign.End : HorizontalAlign.Start) // 设置对齐方式}})}.layoutWeight(1) // 设置布局权重.divider({ strokeWidth: 1, color: '#eee' }) // 设置分隔线}.width('100%') // 设置宽度.height('100%') // 设置高度.padding(10) // 设置内边距.backgroundColor('#f0f0f0') // 设置背景颜色}
}

五、问题优化        

         1、权限配置问题

              存在原因:

                        网络请求失败

                        控制台报错PERMISSION_DENIED

               解决方法:module.josn5配置文件中配置网络权限

// module.json5 配置  
"requestPermissions": [  {  "name": "ohos.permission.INTERNET",  }  
]  

               2、 消息安全性风险

// 消息内容过滤  
private sanitizeMessage(content: string): string {  return content  .replace(/</g, '&lt;')  .replace(/>/g, '&gt;')  .substring(0, 500); // 限制消息长度  
}  

           3. 防止频繁发送

private lastSendTime: number = 0sendMessage() {if (Date.now() - this.lastSendTime < 1000) {promptAction.showToast({ message: '发送太频繁啦!' })return}// ...正常发送逻辑this.lastSendTime = Date.now()
}

五、总结

  1. 测试地址:先用wss://echo.websocket.org这种公共测试服务

  2. 真机调试:记得在手机设置里打开应用的网络权限

  3. 基础样式:先实现功能再美化界面

  4. 错误处理:关键操作添加try-catch防止崩溃

通过这个简化版,开发者可以快速搭建基础聊天功能,再逐步添加进阶特性。建议先跑通基础代码,再按需扩展功能!


http://www.ppmy.cn/news/1584015.html

相关文章

【NLP 48、大语言模型的神秘力量 —— ICL:in context learning】

目录 一、ICL的优势 1.传统做法 2.ICL做法 二、ICL的发展 三、ICL成因的两种看法 1.meta learning 2.Bayesian Inference 四、ICL要点 ① 语言模型的规模 ② 提示词prompt中提供的examples数量和顺序 ③ 提示词prompt的形式&#xff08;format&#xff09; 五、fine-tune VS I…

Go语言中html/template模块详细功能介绍与示例

Go语言的 html/template 模块是专门用于生成安全 HTML 输出的模板引擎&#xff0c;支持自动转义以防止 XSS 攻击。以下是该模块的核心方法及用法示例&#xff1a; 1. 基础模板解析与渲染 template.Parse 和 template.Execute 解析模板字符串并渲染数据。 package mainimport…

小林coding-12道Spring面试题

1.说一下你对 Spring 的理解?spring的核心思想说说你的理解&#xff1f; 2.Spring IoC和AOP 介绍一下?Spring的aop介绍一下?IOC和AOP是通过什么机制来实现的?怎么理解SpringIoc&#xff1f;依赖倒置&#xff0c;依赖注入&#xff0c;控制反转分别是什么&#xff1f;依赖注…

隐匿视角:七款局域网屏幕监控软件对企业数字神经系统架构的重塑效应探究

在当今竞争激烈的商业环境中&#xff0c;企业管理者对于全面掌握公司运营状况&#xff0c;尤其是员工在工作时间的状态有着强烈需求。局域网屏幕监控技术作为一种有效的管理手段&#xff0c;能够使管理者实时洞察员工的计算机操作行为&#xff0c;从而提升管理效率&#xff0c;…

Web Services 简介

Web Services 简介 概述 Web Services 是一种网络服务技术,允许不同的应用程序通过互联网进行交互和数据交换。随着互联网的普及和发展,Web Services 已经成为企业级应用中不可或缺的一部分。本文将详细介绍 Web Services 的概念、特点、应用场景以及相关的技术架构。 什么…

【C++标准IO库】输出缓冲区的管理

目录 一、输出缓冲区的基本概念 1.1 什么是输出缓冲区 1.2 输出缓冲区的工作原理 1.3 输出缓冲区的优点 1.4 与缓冲区管理相关的函数和类 二、刷新输出缓冲区的方法 2.1 使用操纵符刷新缓冲区 2.2 程序正常结束时刷新缓冲区 2.3 缓冲区满时自动刷新 2.4 使用 setbuf …

数据不互通、审批慢?如何实现多系统智能协同

在企业信息化建设的过程中&#xff0c;数据孤岛和复杂的审批流程常常成为实现高效协同的巨大障碍。对于许多组织来说&#xff0c;面对越来越复杂的业务需求&#xff0c;如何实现多系统智能协同不仅关乎效率&#xff0c;更直接影响企业的竞争力。 数据不互通和审批流程慢的痛点…

李宏毅机器学习笔记06 | 鱼和熊掌可以兼得的机器学习 - 内容接宝可梦

本章提要 深度学习可以在较少参数量的情况下得到比较低的loss&#xff1a; h a l l a r g min ⁡ h ∈ H L ( h , D a l l ) h^{all}arg \min_{h \in H}L(h,D_{all}) hallargminh∈H​L(h,Dall​) 引入 如何权衡模型的复杂程度 Tradeoff of Model Complexity 理论上&#…