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