鸿蒙上实现简单的聊天功能需求分析:- 连接指定 IP 和端口
- 显示接收的内容
- 具有发送的功能
[size=; font-size: 1.176em,1.176em]控件介绍
①Socket 连接场景介绍:应用通过 Socket 进行数据传输,支持 TCP 和 UDP 两种协议。接口说明:Socket 连接主要由 socket 模块提供。具体接口说明如下表。
基本例程(参考我之前的家庭医生终端系统):import socket
from '@ohos.net.socket';
let tcp = socket.constructTCPSocketInstance();tcp.bind({address:
'0.0.0.0', port:
12121, family:
1},
err => {
if (err) {
console.log(
'bind fail');
return;}
console.log(
'bind success');})tcp.on(
'message',
value => {
console.log(
"on message, message:" + value.message +
", remoteInfo:" + value.remoteInfo)
let da = resolveArrayBuffer(value.message);
let dat_buff =
String(da);
//此处对接受到的数据进行处理});
//将接受到的数据转化为文本型 function resolveArrayBuffer(message){
if (message
instanceof ArrayBuffer) {
let dataView =
new DataView(message)
let str =
""for (
let i =
0;i < dataView.byteLength; ++i) {
let c =
String.fromCharCode(dataView.getUint8(i))
if (c !==
"n") {str += c}}
return str;}}
//数据的发送函数function send_once(Con_buff) {
if (flag ==
false) {
let promise = tcp.connect({ address: { address:
'xxx.xxx.xxx.xxx', port: xxxx, family:
1 }, timeout:
2000 });promise.then(
() => {
console.log(
'connect success');flag =
true;tcp.send({data: Con_buff},
err => {
if (err) {
console.log(
'send fail');
return;}
console.log(
'send success');})}).catch(
err => {
console.log(
'connect fail');});}
else if (flag ==
true) {tcp.send({data: Con_buff},
err => {
if (err) {
console.log(
'send fail');
return;}
console.log(
'send success');})}}
②AppStorage 与组件同步在管理组件拥有的状态中,已经定义了如何将组件的状态变量与父组件或祖先组件中的 @State 装饰的状态变量同步,主要包括 @Prop、@Link、@Consume。本章节定义如何将组件变量与 AppStorage 同步,主要提供 @StorageLink 和 @StorageProp 装饰器。@StorageLink 装饰器组件通过使用 @StorageLink(key) 装饰的状态变量,与 AppStorage 建立双向数据绑定,key 为 AppStorage 中的属性键值。当创建包含 @StorageLink 的状态变量的组件时,该状态变量的值将使用 AppStorage 中的值进行初始化。在 UI 组件中对 @StorageLink 的状态变量所做的更改将同步到 AppStorage,并从 AppStorage 同步到任何其他绑定实例中,如 PersistentStorage 或其他绑定的 UI 组件。@StorageProp 装饰器组件通过使用 @StorageProp(key) 装饰的状态变量,将与 AppStorage 建立单向数据绑定,key 标识 AppStorage 中的属性键值。当创建包含 @StoageProp 的状态变量的组件时,该状态变量的值将使用 AppStorage 中的值进行初始化。AppStorage 中的属性值的更改会导致绑定的 UI 组件进行状态更新。let varA = AppStorage.Link(
'varA')
let envLang = AppStorage.Prop(
'languageCode')
@Entry@Componentstruct ComponentA {
@StorageLink(
'varA') varA:
number =
2@StorageProp(
'languageCode') lang:
string =
'en'private label:
string =
'count'private aboutToAppear() {
this.label = (
this.lang ===
'zh') ?
'数' :
'Count'}build() {Row({ space:
20 }) {Button(
`${this.label}: ${this.varA}`).onClick(
() => {AppStorage.Set<
number>(
'varA', AppStorage.Get<
number>(
'varA') +
1)})Button(
`lang: ${this.lang}`).onClick(
() => {
if (
this.lang ===
'zh') {AppStorage.Set<
string>(
'languageCode',
'en')}
else {AppStorage.Set<
string>(
'languageCode',
'zh')}
this.label = (
this.lang ===
'zh') ?
'数' :
'Count'})}}}
即通过 AppStorage.Link 和 @StorageLink 的方式,可实现外部动态刷新 Text 组件和 image 组件(等等之类都可以),方便我们在全局调用时更新数据。[size=; font-size: 1.176em,1.176em]UI 设计
本项目的基本内容是可以在预览器中看到的,所以先在预览器中简单设计 UI。①基本界面
以后不会大时间讲解 UI 了,会直接放成品,且我的源码都在 Gitee 仓上存在,需要的可以自己下载,会着重体现程序部分。②接口绑定首先是接收框处的变量绑定:let Rc_message = AppStorage.Link(
'Rc_message')
@StorageLink(
'Rc_message') Rc_message:
String =
'收到消息'Text(
`${this.Rc_message}`).width(
"98%").height(
"35%").borderStyle(BorderStyle.Solid).borderWidth(
8).borderColor(
0xAFEEEE).borderRadius(
20).fontSize(
25)
③TCP 回调设置tcp.
on(
'message',
value => {console.log(
"on message, message:" +
value.message +
", remoteInfo:" +
value.remoteInfo)
let da = resolveArrayBuffer(
value.message);
let dat_buff = String(da);AppStorage.Set<String>(
'Rc_message',dat_buff);
//AppStorage.Set<String>('ID_1_stata','rgba(0, 109, 229, 0.95)');});
该部分实现聊天框内部的文字刷新。④IP 设置这里我是使用的合宙的 TCP 工具[wstool (luatos.com)](
在此处修改 IP 和端口:
⑤远端模拟器
在模拟器中打开如上。[size=; font-size: 1.176em,1.176em]实际测试
使用模拟器进行发送:
在 TCP 工具处有接收到内容,此时进行回复。
在 APP 端可以接收到并显示(暂时可能只支持英文接受显示)。



[size=; font-size: 1.176em,1.176em]动态图
TCP 助手显示如下:
本项目 Gitee 仓地址:https:
//gitee.com/lalhan/eTs_Study