在編制工程時(shí),有時(shí)需要在兩個(gè)客戶端間進(jìn)行數(shù)據(jù)通信。比如,客戶端A和客戶端B需要實(shí)現(xiàn)聊天功能,當(dāng)客戶端A在畫(huà)面中敲入一行文字“你好!”時(shí),希望在客戶端B的相應(yīng)畫(huà)面中立刻收到并顯示這行文本。同樣,客戶端B也可以向客戶端A發(fā)送文本。
在老版本軟件中,實(shí)現(xiàn)這項(xiàng)功能將是一件很麻煩的事。我們自然想到使用數(shù)據(jù)庫(kù)點(diǎn)來(lái)進(jìn)行通訊。我們可以在客戶端A中建立一個(gè)數(shù)據(jù)庫(kù)點(diǎn)AtoB,通過(guò)遠(yuǎn)程數(shù)據(jù)源將其參數(shù)DESC連接到客戶端B中的AtoB.DESC上,當(dāng)客戶端A畫(huà)面輸入文字時(shí),立刻將其賦值給AtoB.DESC,由數(shù)據(jù)庫(kù)通知另一端的AtoB.DESC發(fā)生變化,還要在客戶端B上編寫(xiě)數(shù)據(jù)改變腳本,當(dāng)AtoB.DESC改變時(shí)通知客戶端B的畫(huà)面做相應(yīng)反應(yīng)。同樣,重復(fù)上一過(guò)程實(shí)現(xiàn)由客戶端B到客戶端A的數(shù)據(jù)通知,而且我們需要再創(chuàng)建一對(duì)新的數(shù)據(jù)庫(kù)點(diǎn)BtoA,因?yàn)榱奶爝^(guò)程中數(shù)據(jù)往返是并行的,所以通訊應(yīng)該在兩對(duì)數(shù)據(jù)庫(kù)點(diǎn)中進(jìn)行。
倘若我們發(fā)送的不僅僅是簡(jiǎn)單文本,而是其他信息呢?比如:一條包含若干整型、實(shí)型、字符串等信息的數(shù)據(jù),一條關(guān)于畫(huà)面切換、腳本執(zhí)行的指令文本。盡管依然可以通過(guò)一個(gè)數(shù)據(jù)庫(kù)點(diǎn)的DESC參數(shù)進(jìn)行傳遞,可是在接收端如何將所接收到的信息按期望的格式解析呢?也許可以考慮再創(chuàng)建若干數(shù)據(jù)庫(kù)點(diǎn),每個(gè)數(shù)據(jù)庫(kù)點(diǎn)只傳遞一個(gè)數(shù)據(jù),這樣一來(lái)又帶來(lái)新的問(wèn)題:無(wú)法預(yù)知數(shù)據(jù)的個(gè)數(shù)、格式,解析這些數(shù)據(jù)也會(huì)帶來(lái)大量腳本編寫(xiě)工作;如果是多個(gè)客戶端間通訊,那么上面所說(shuō)的工作將要重復(fù)的次數(shù)=從m個(gè)客戶端中取出2個(gè)客戶端的組合個(gè)數(shù),例如:從3個(gè)客戶端中取出2個(gè)客戶端的組合個(gè)數(shù)為3、從10個(gè)客戶端中取出2個(gè)客戶端的組合數(shù)是50。那么這將是一項(xiàng)令人望而卻步的工作。另外,新增的數(shù)據(jù)庫(kù)點(diǎn)無(wú)疑對(duì)項(xiàng)目成本來(lái)說(shuō)是個(gè)挑戰(zhàn)。
有沒(méi)有一種手段,可以不使用數(shù)據(jù)庫(kù)點(diǎn)就能實(shí)現(xiàn)客戶端間數(shù)據(jù)通信,而且傳遞的數(shù)據(jù)以規(guī)范的形式發(fā)送和接收,并提供方便的解析方法?答案是:有。紫金橋軟件6.5版本新增的會(huì)話組件就可以專門(mén)解決這類問(wèn)題。
簡(jiǎn)介
會(huì)話組件是一種實(shí)現(xiàn)客戶端之間通訊的窗口組件。它通過(guò)同一數(shù)據(jù)網(wǎng)絡(luò)中的某個(gè)DB作為通訊中介,在不同客戶端之間實(shí)現(xiàn)異步數(shù)據(jù)通信,其運(yùn)行的一般原理圖如下。
 
會(huì)話組件運(yùn)行在客戶端的窗口中,而db.exe僅僅作為數(shù)據(jù)通信的中介。上圖中帶箭頭的直線代表數(shù)據(jù)流向,其中紅色的直線及虛線表示了客戶端A發(fā)送給客戶端B的數(shù)據(jù)走向情況,藍(lán)色的直線及虛線則表示了客戶端B發(fā)送給客戶端A的數(shù)據(jù)走向情況。在這個(gè)數(shù)據(jù)網(wǎng)絡(luò)中,任何客戶端之間都可以使用會(huì)話組件進(jìn)行數(shù)據(jù)通信。
概念介紹
客戶端:指view.exe或infoview.ocx(IE客戶端)。
通信組:在一個(gè)網(wǎng)絡(luò)中所有需要相互通信的客戶端組成了一個(gè)通信組。這個(gè)網(wǎng)絡(luò)可以是以太網(wǎng)網(wǎng)絡(luò),可以是串口網(wǎng)等。通信組中的任何一個(gè)成員均可以和組中其他成員進(jìn)行數(shù)據(jù)通信。通信組可以交叉,即一個(gè)客戶端可以同時(shí)為兩個(gè)通信組中的成員。
會(huì)話名:在一個(gè)通信組中,每個(gè)會(huì)話組件對(duì)象在通信時(shí)使用的唯一標(biāo)識(shí)。
中介節(jié)點(diǎn):在一個(gè)通信組中,為所有成員客戶端提供通訊媒介的網(wǎng)絡(luò)節(jié)點(diǎn)。同一個(gè)組中的所有客戶端的中介節(jié)點(diǎn)必須指向該網(wǎng)絡(luò)中的同一個(gè)節(jié)點(diǎn)。這個(gè)節(jié)點(diǎn)可以是這個(gè)網(wǎng)絡(luò)中的任意一個(gè)有DB.exe運(yùn)行的節(jié)點(diǎn),該節(jié)點(diǎn)所在計(jì)算機(jī)中的客戶端可以不參與數(shù)據(jù)通信。
具體實(shí)現(xiàn)
- 配置中介數(shù)據(jù)源
選定中介節(jié)點(diǎn)后,在需要進(jìn)行數(shù)據(jù)通信的客戶端中建立指向中介節(jié)點(diǎn)的數(shù)據(jù)源,如果本機(jī)恰好為中介節(jié)點(diǎn),那么使用“本地”數(shù)據(jù)源就可以了。
- 創(chuàng)建組件對(duì)象
進(jìn)入客戶端工程的組態(tài)環(huán)境中,創(chuàng)建一個(gè)窗口,然后打開(kāi)子圖選擇畫(huà)面,找到“組件、復(fù)雜精靈/高級(jí)”選項(xiàng)卡,雙擊“會(huì)話組件”圖標(biāo),一個(gè)會(huì)話組件被創(chuàng)建在當(dāng)前窗口中,將其命名。
- 配置組件對(duì)象
雙擊組件,出現(xiàn)配置界面,如下圖所示:
 
在“數(shù)據(jù)源”處選擇事先指定的中介數(shù)據(jù)源。
在“自身名稱”處填寫(xiě)本會(huì)話組件對(duì)象的會(huì)話名。
在“對(duì)方名稱”處填寫(xiě)當(dāng)前發(fā)送數(shù)據(jù)的目標(biāo)會(huì)話組件對(duì)象的會(huì)話名。
- 數(shù)據(jù)發(fā)送
數(shù)據(jù)發(fā)送的是通過(guò)會(huì)話組件的提供的兩個(gè)函數(shù)來(lái)實(shí)現(xiàn)的:
BOOL Send(String FuncionName, ObDataTable Tab)
BOOL SendTo(String DestName, String FuncionName, ObDataTable Tab)
這兩個(gè)函數(shù)的功能是向目標(biāo)客戶端發(fā)送一條信息,其中參數(shù)Tab為ObDataTable 類型的對(duì)象指針,Tab中包含了本次發(fā)送的所有信息。參數(shù)DestName為指定的目標(biāo)客戶端的會(huì)話名。也就是說(shuō),如果使用函數(shù)Send則目標(biāo)客戶端為組態(tài)時(shí)指定的客戶端,如果使用函數(shù)SendTo則可以動(dòng)態(tài)指定目標(biāo)客戶端。
參數(shù)FuncionName為目標(biāo)客戶端會(huì)話組件所在窗口的自定義函數(shù)名,這個(gè)函數(shù)是回調(diào)函數(shù),當(dāng)目標(biāo)客戶端收到這條信息后會(huì)自動(dòng)調(diào)用這個(gè)窗口函數(shù)。其函數(shù)形式規(guī)定為:
void FuncName(String SrcName, ObDataTable& Tab)
其中參數(shù)SrcName為本條信息的發(fā)送客戶端的會(huì)話名,Tab為發(fā)送的內(nèi)容。
- 數(shù)據(jù)接收
數(shù)據(jù)接收是通過(guò)上述回調(diào)函數(shù)來(lái)處理的。在接收端會(huì)話組件對(duì)象所在窗口中創(chuàng)建回調(diào)函數(shù),注意回調(diào)函數(shù)的名字及參數(shù)類型一定要與規(guī)定一致。用戶可以在回調(diào)函數(shù)體內(nèi)編寫(xiě)收到信息后的處理動(dòng)作。
在一個(gè)雙向數(shù)據(jù)通信的結(jié)構(gòu)體系中,一個(gè)客戶端既是數(shù)據(jù)發(fā)送端同時(shí)也是數(shù)據(jù)接收端,所以每個(gè)客戶端都要實(shí)現(xiàn)數(shù)據(jù)發(fā)送和數(shù)據(jù)接收。
進(jìn)階
- 會(huì)話組件對(duì)象與客戶端
會(huì)話組件的本質(zhì)是窗口組件,這就意味著同一客戶端中可以創(chuàng)建多個(gè)會(huì)話組件對(duì)象,但是每個(gè)會(huì)話組件對(duì)象應(yīng)該擁有唯一的會(huì)話名?梢酝ㄟ^(guò)讓這些會(huì)話組件對(duì)象指向不同中介數(shù)據(jù)源,來(lái)實(shí)現(xiàn)與不同通信組成員客戶端的通訊。
- 動(dòng)態(tài)切換中介數(shù)據(jù)源
假設(shè)在組態(tài)時(shí)指定了會(huì)話組件的中介數(shù)據(jù)源為DS1,那么在運(yùn)行時(shí)可以通過(guò)調(diào)用數(shù)據(jù)源函數(shù)SetNetAddr來(lái)動(dòng)態(tài)切換其指向的網(wǎng)絡(luò)結(jié)點(diǎn),從而切換中介數(shù)據(jù)源。
- 如何發(fā)送廣播
通過(guò)會(huì)話組件提供的函數(shù)void GetUserNames(String Array Names),可以在運(yùn)行時(shí)得到當(dāng)前通信組中所有通信成員的會(huì)話名,然后針對(duì)所有會(huì)話名發(fā)送信息以便達(dá)到廣播的目的。
- 通過(guò)會(huì)話組件能傳遞哪些數(shù)據(jù)
從會(huì)話組件的發(fā)送及回調(diào)函數(shù)來(lái)看,數(shù)據(jù)是通過(guò)數(shù)據(jù)表對(duì)象(ObDataTable)來(lái)傳遞的,ObDataTable是一種比較實(shí)用的表格,可以同時(shí)傳遞多行多列的文本、數(shù)值等數(shù)據(jù),但是無(wú)法直接傳送文件。
- 關(guān)于超時(shí)
因?yàn)樯婕熬W(wǎng)絡(luò)通信,所以在網(wǎng)絡(luò)狀況較差甚至是斷開(kāi)的情況下無(wú)法保證數(shù)據(jù)通信的暢通性和及時(shí)性,因此需要自行處理發(fā)送超時(shí)。一般在接收到數(shù)據(jù)后應(yīng)該馬上返回一條信息告知發(fā)送端本條數(shù)據(jù)已經(jīng)成功接收,如果發(fā)送端沒(méi)有在規(guī)定時(shí)間內(nèi)收到反饋信息,則認(rèn)為是超時(shí)。
|