深入浅出学习eTs—TCP聊天室(十九)

系统 OpenHarmony
本章节我们来实现一个TCP聊天的功能。

想了解更多关于开源的内容,请访问:

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

一、需求分析

#盲盒+码##深入浅出学习eTs#(十九)TCP聊天室-开源基础软件社区

本章节我们来实现一个TCP聊天的功能

  • 连接指定IP和端口
  • 显示接收的内容
  • 具有发送的功能

二、控件介绍

1、Socket连接

场景介绍

应用通过Socket进行数据传输,支持TCP和UDP两种协议。

接口说明

Socket连接主要由socket模块提供。具体接口说明如下表。

接口名

功能描述

constructUDPSocketInstance()

创建一个UDPSocket对象。

constructTCPSocketInstance()

创建一个TCPSocket对象。

bind()

绑定IP地址和端口。

send()

发送数据。

close()

关闭连接。

getState()

获取Socket状态。

connect()

连接到指定的IP地址和端口(仅TCP支持)

getRemoteAddress()

获取对端Socket地址(仅TCP支持,需要先调用connect方法)

on(type: ‘message’)

订阅Socket连接的接收消息事件。

off(type: ‘message’)

取消订阅Socket连接的接收消息事件。

on(type: ‘close’)

订阅Socket连接的关闭事件。

off(type: ‘close’)

取消订阅Socket连接的关闭事件。

on(type: ‘error’)

订阅Socket连接的Error事件。

off(type: ‘error’)

取消订阅Socket连接的Error事件。

on(type: ‘listening’)

订阅UDPSocket连接的数据包消息事件(仅UDP支持)。

off(type: ‘listening’)

取消订阅UDPSocket连接的数据包消息事件(仅UDP支持)。

on(type: ‘connect’)

订阅TCPSocket的连接事件(仅TCP支持)。

off(type: ‘connect’)

取消订阅TCPSocket的连接事件(仅TCP支持)。

基本例程(参考我之前的家庭医生终端系统)。

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');
})
}
}

2、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
@Component
struct 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组件(等等之类都可以),方便我们在全局调用时更新数据。

三、UI设计

本项目的基本内容是可以在预览器中看到的,所以先在预览器中简单设计UI

1、基本界面

#盲盒+码##深入浅出学习eTs#(十九)TCP聊天室-开源基础软件社区

以后不会大时间讲解UI了,会直接放成品,且我的源码都在Gitee仓上存在,需要的可以自己下载,会着重体现程序部分。

2、接口绑定

首先是接收框处的变量绑定。

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)

3、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)');
});

该部分实现聊天框内部的文字刷新。

4、IP设置

这里我是使用的合宙的TCP工具[wstool (luatos.com)](。

#盲盒+码##深入浅出学习eTs#(十九)TCP聊天室-开源基础软件社区

在此处修改IP和端口。

#盲盒+码##深入浅出学习eTs#(十九)TCP聊天室-开源基础软件社区

5、远端模拟器

#盲盒+码##深入浅出学习eTs#(十九)TCP聊天室-开源基础软件社区

在模拟器中打开如上。

四、实际测试

#盲盒+码##深入浅出学习eTs#(十九)TCP聊天室-开源基础软件社区

使用模拟器进行发送。

#盲盒+码##深入浅出学习eTs#(十九)TCP聊天室-开源基础软件社区

在TCP工具处有接收到内容,此时进行回复。

#盲盒+码##深入浅出学习eTs#(十九)TCP聊天室-开源基础软件社区

在APP端可以接收到并显示(暂时可能只支持英文接受显示)。

#盲盒+码##深入浅出学习eTs#(十九)TCP聊天室-开源基础软件社区

#盲盒+码##深入浅出学习eTs#(十九)TCP聊天室-开源基础软件社区

#盲盒+码##深入浅出学习eTs#(十九)TCP聊天室-开源基础软件社区

#盲盒+码##深入浅出学习eTs#(十九)TCP聊天室-开源基础软件社区

五、动态图

#盲盒+码##深入浅出学习eTs#(十九)TCP聊天室-开源基础软件社区

TCP助手显示如下:

#盲盒+码##深入浅出学习eTs#(十九)TCP聊天室-开源基础软件社区

想了解更多关于开源的内容,请访问:

​51CTO 开源基础软件社区​

​https://ost.51cto.com​​。

责任编辑:jianghua 来源: 51CTO开源基础软件社区
相关推荐

2022-12-01 08:20:00

2023-04-03 15:32:21

学习eTsHTTP协议

2009-11-30 16:46:29

学习Linux

2013-09-16 09:56:29

TCP协议网络协议send

2021-03-16 08:54:35

AQSAbstractQueJava

2011-07-04 10:39:57

Web

2017-07-02 18:04:53

块加密算法AES算法

2012-05-21 10:06:26

FrameworkCocoa

2021-07-20 15:20:02

FlatBuffers阿里云Java

2019-01-07 15:29:07

HadoopYarn架构调度器

2022-09-26 09:01:15

语言数据JavaScript

2009-06-18 12:59:39

Criteria Qu深入浅出Hiberna

2014-08-05 09:27:20

TCP网络协议

2018-11-09 16:24:25

物联网云计算云系统

2019-11-11 14:51:19

Java数据结构Properties

2012-02-21 13:55:45

JavaScript

2009-11-18 13:30:37

Oracle Sequ

2022-12-02 09:13:28

SeataAT模式

2022-10-31 09:00:24

Promise数组参数

2021-04-27 08:54:43

ConcurrentH数据结构JDK8
点赞
收藏

51CTO技术栈公众号