一、需求分析
本章節我們來實現一個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('varA', AppStorage.Get('varA') + 1) }) Button(`lang: ${this.lang}`) .onClick(() => { if (this.lang === 'zh') { AppStorage.Set('languageCode', 'en') } else { AppStorage.Set('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('Rc_message',dat_buff); //AppStorage.Set('ID_1_stata','rgba(0, 109, 229, 0.95)'); });
該部分實現聊天框內部的文字刷新
(4)IP設置
這里我是使用的合宙的TCP工具[wstool (luatos.com)](
在此處修改IP和端口
(5)遠端模擬器
在模擬器中打開如上
四、實際測試
使用模擬器進行發送
在TCP工具處有接收到內容,此時進行回復
在APP端可以接收到并顯示(暫時可能只支持英文接受顯示)
五、動態圖
TCP助手顯示如下
編輯:黃飛
-
TCP
+關注
關注
8文章
1377瀏覽量
79183 -
UDP
+關注
關注
0文章
327瀏覽量
34009 -
ets
+關注
關注
0文章
20瀏覽量
1626 -
OpenHarmony
+關注
關注
25文章
3744瀏覽量
16473
發布評論請先 登錄
相關推薦
評論