news 2026/4/16 11:55:07

实现一个纯血鸿蒙版(HarmonyOS)的聊天Demo,并可与其它PC、手机端互通!

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
实现一个纯血鸿蒙版(HarmonyOS)的聊天Demo,并可与其它PC、手机端互通!

一. 开发环境

开发工具:DevEco Studio 5.1

开发语言:ArkTS

测试手机:华为 Mate 70

二. Demo 实现的功能

本文ESFramework的鸿蒙版Demo演示了以下功能:

(1)客户端用户上下线时,通知其他在线用户。

(2)当客户端与服务端网络断开时,进行自动重连,当网络恢复后,重连成功。

(3)所有在线用户之间可以进行文字聊天。

(4)文件传送。

(5)消息同步调用。

(6)重登陆模式。当同名的用户登陆时,会把前面的用户挤掉。

这里有该Demo运行的效果 演示视频。

文末有该Demo鸿蒙端实现的源码,下载源码后,对照着这篇文章看,会更容易理解。

三. Harmony鸿蒙客户端实现说明

源码解压后,在DevEco Studio中打开Demo项目,其结构如下所示:

1. 文件目录结构

image

2.定义信息类型

在本demo中,我们定义5个信息类型,分别表示文字聊天消息(直接发送给对方),文字聊天消息(由服务端转发),图片消息、撤回消息,以及客户端同步调用服务端。其定义如下:

复制代码

enum InformationTypes{

/// 文字(表情)聊天信息

TextChat = 0,

/// 文字(表情)聊天信息 (由服务端转发给消息接收方)

TextChat4Transit = 1,

/// 图片聊天信息

ImageChat = 2,

/// 收到消息发送者 撤回消息请求

RecallMsg = 3,

/// 客户端异步调用服务端

ClientSyncCallServer = 4,

}

复制代码

3.实现自定义信息处理器

客户端的utils里的customizeHandler实现了ICustomizeHandler接口,其主要实现HandleInformation方法,来处理收到的聊天信息。

handleInformation(sourceUserID: string, informationType: number, info: number[]): void{

......

}

4.index.ets 登录页

登录页的样式如图所示:

Screenshot_2025-10-16T173824

输入ip、账号、密码后,点击登录,输入的数据会用于初始化RapidPassiveEngine以登录。代码如下:

复制代码

//通过@Provide标记engine并定义,可以将engine与后代组件双向同步

@Provide('engine') engine:RapidPassiveEngine|null = null

//通过@State将数据设置为响应式的数据

@State ip:string = '192.168.0.244'

@State userId:string = '101'

@State pwd:string = '12'

//点击登录按钮

Button('登录',{ type: ButtonType.Normal }).onClick(()=>{

//新建一个ESFramework引擎

this.engine = new RapidPassiveEngine()

//通过initialize方法,将登录的ip账号密码传进ESFramework

this.engine.initialize(this.userId, this.pwd ,this.ip,

4530,customizeHandlers,(res)=>{

......

})

})

复制代码

5.home.ets 好友/功能页

好友页里实现了好友列表的展示,收到消息后会将消息展示在好友名下方,好友页样式图如下:

Screenshot_2025-10-17T084257

当用户登录成功后,便可以从服务器获取所有在线联系人,然后客户端只需要处理这些信息即可渲染页面,处理信息代码如下:

复制代码

//创建一个User接口

export interface User{

username:string,

headImg:string,

clientType:ClientType

}

//在线用户列表

@State userList:Array<User> = []

//登录的时候,直接通过新建的引擎获取服务器里所有的在线成员,res为所有在线成员数组

this.engine.ContactsOutter.getAllOnlineContacts((res:Array<string>)=>{

//在这里添加用户列表

......

})

//监听联系人上线事件

this.engine.ContactsOutter.event["ContactsDeviceConnected"] =()=>{

//如果有联系人上线,将会进入这个函数

......

}

复制代码

用户列表渲染主要代码如下:

复制代码

Column() {

//使用List来渲染用户列表

List() {

//通过foreach获取到每一个用户的信息

ForEach(this.userList, (item:User) => {

ListItem() {

Flex({direction:FlexDirection.Row,alignItems:ItemAlign.Center}){

Image(item.headImg)

Flex({direction:FlexDirection.Column,justifyContent:FlexAlign.SpaceBetween}){

Text(`${item.username}`)

}

}

}

})

}

}

复制代码

6. chat.ets 聊天页

当有联系人向我发送消息,消息各项信息会进入已经实现的customizeHandler里的handleInformation里,客户端处理这些信息即可渲染画面,聊天页的样式如图所示:

Screenshot_2025-10-13T094515

处理相关代码如下:

复制代码

//在utils.ets文件里的customizeHandler类里,需要设置信息处理回调函数,外部才能通过传一个callback获取到收到消息的信息

private handleInformationCallback ?: Function;

//设置信息处理回调函数

setHandleInformationCallback(callback : Function) : void {

this.handleInformationCallback = callback;

}

//处理来自其他用户的信息(包括大数据块信息)

handleInformation(sourceUserID: string, informationType: number, info: number[]): void {

if (this.handleInformationCallback) {

//将收到的信息传递到信息处理回调函数里

this.handleInformationCallback(sourceUserID, informationType,util.getStr(info))

}

}

//在index.ets里

//设置聊天记录字典,键为用户id,值为聊天记录数组对象,message为聊天记录数据接口。

OrayDic为ESFramework内置的设置字典的方法

@Provide('userMessages') userMessages: OrayDic<string, Array<Message>> = new OrayDic();

//获取自定义消息处理器

const customizeHandlers = new customizeHandler()

//设置消息的监听

customizeHandlers.setHandleInformationCallback((sendID:string,informationType:number,chatInfo:string)=>{

//收到的文字图片信息都会进入这里,在这里处理聊天记录

......

})

复制代码

聊天记录主要渲染代码如下:

复制代码

Column(){

//通过List渲染聊天记录

List(){

//通过ForEach来获取每一个聊天信息

ForEach(this.currentUserMessages,(item:Message)=>{

ListItem(){

Column(){

//文字信息

if(item.informationType == InformationTypes.TextChat || item.informationType == InformationTypes.TextChat4Transit){

//对方普通文字消息

if(item.SpeakerID == this.user?.username){

......

}

//我方普通文字信息

else{

......

}

//图片信息

if(item.informationType == InformationTypes.ImageChat) {

//对方图片信息

if(item.SpeakerID == this.user?.username) {

......

}

//我方图片消息

else{

......

}

//文件信息

if(item.informationType == InformationTypes.File){

//对方文件消息

if(item.SpeakerID == this.user?.username){

......

}

//我方文件信息

else{

......

}

//撤回信息

// if(item.informationType === InformationTypes.RecallMsg)

if(item.informationType == InformationTypes.RecallMsg) {

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/14 18:43:44

Spring Boot 接口全链路测试全攻略:从单元到生产级验证

Spring Boot 接口全链路测试全攻略:从单元到生产级验证 在分布式微服务系统中,接口稳定性直接决定了用户体验和业务连续性。 本文将系统性介绍 8 种核心测试方法,并额外补充 7 个进阶策略,帮助你从开发到生产,构建一个全面的测试体系,让 Spring Boot 接口稳定性提升 100…

作者头像 李华
网站建设 2026/4/12 9:50:31

前端动画性能优化

先说说为啥动画性能这么要命。现在用户可没耐心等你页面慢慢加载&#xff0c;动画一卡顿&#xff0c;轻则体验打折&#xff0c;重则流失用户。更别提搜索引擎现在把页面交互流畅度也算进排名因素了&#xff0c;你要敢让动画掉帧&#xff0c;SEO排名分分钟往下掉。而且移动端设备…

作者头像 李华
网站建设 2026/4/15 11:49:50

计算机Java毕设实战-基于Springboot网上蛋糕售卖店管理系统的设计与实现基于springboot的云与糖蛋糕购物平台系统的设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/4/11 19:32:59

Java毕设选题推荐:基于Springboot的网上蛋糕售卖店管理系统设计基于springboot的云与糖蛋糕购物平台系统的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/4/14 23:01:44

用MATLAB实现眼球检测与注视跟踪:从人脸到瞳孔的探索之旅

使用 MATLAB 通过人脸检测、眼睛区域检测、瞳孔检测和眼睛跟踪进行眼球检测和眼睛注视跟踪。 通过摄像头捕捉人脸&#xff0c;主要使用Viola-Jones人脸检测器检测人脸&#xff0c;然后再检测人眼&#xff0c;通过霍夫圆检测选择眼球&#xff0c;并判断眼球在眼睛中的位置。 在计…

作者头像 李华
网站建设 2026/4/12 10:23:45

课程论文还在熬夜凑字数?虎贲等考 AI:让学术写作高效又拿分

对于大学生而言&#xff0c;课程论文是贯穿整个求学阶段的 “常规任务”。从公共课的短篇报告到专业课的深度论文&#xff0c;既要满足 “专业性达标、原创无抄袭” 的学术要求&#xff0c;又要在繁重的课业压力下快速完成 —— 不少同学陷入 “为凑字数熬夜、因重复率焦虑、因…

作者头像 李华