#盲盒+码##深入浅出学习eTs#(十九)TCP聊天室

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#盲盒+码##深入浅出学习eTs#(十九)TCP聊天室相关的知识,希望对你有一定的参考价值。

【本文正在参加「盲盒」+码有奖征文活动】https://ost.51cto.com/posts/19288

本项目Gitee仓地址:深入浅出eTs学习: 带大家深入浅出学习eTs (gitee.com)

一、需求分析

本章节我们来实现一个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)基本界面

以后不会大时间讲解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)]( 在此处修改IP和端口

(5)远端模拟器

在模拟器中打开如上

四、实际测试

使用模拟器进行发送 在TCP工具处有接收到内容,此时进行回复 在APP端可以接收到并显示(暂时可能只支持英文接受显示)

五、动态图

TCP助手显示如下

本文作者:程皖Orz

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

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

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

以上是关于#盲盒+码##深入浅出学习eTs#(十九)TCP聊天室的主要内容,如果未能解决你的问题,请参考以下文章

#盲盒+码#FFH学习设备开发之Hi3861-UDP-广播

Linux疑难杂症解决方案100篇(十九)-什么是TCP协议中的“三次握手,四次挥手”?带你深入探讨下

Linux疑难杂症解决方案100篇(十九)-什么是TCP协议中的“三次握手,四次挥手”?带你深入探讨下

#盲盒+码# #跟着小白一起学鸿蒙#HAP应用调用so库方法

#盲盒+码# FFH为Wifi-lot小车做一个遥控器应用

程序化生成雪花滑雪运动数字盲盒