在編制工程時,有時需要在兩個客戶端間進行數據通信。比如,客戶端A和客戶端B需要實現聊天功能,當客戶端A在畫面中敲入一行文字“你好!”時,希望在客戶端B的相應畫面中立刻收到并顯示這行文本。同樣,客戶端B也可以向客戶端A發送文本。
在老版本軟件中,實現這項功能將是一件很麻煩的事。我們自然想到使用數據庫點來進行通訊。我們可以在客戶端A中建立一個數據庫點AtoB,通過遠程數據源將其參數DESC連接到客戶端B中的AtoB.DESC上,當客戶端A畫面輸入文字時,立刻將其賦值給AtoB.DESC,由數據庫通知另一端的AtoB.DESC發生變化,還要在客戶端B上編寫數據改變腳本,當AtoB.DESC改變時通知客戶端B的畫面做相應反應。同樣,重復上一過程實現由客戶端B到客戶端A的數據通知,而且我們需要再創建一對新的數據庫點BtoA,因為聊天過程中數據往返是并行的,所以通訊應該在兩對數據庫點中進行。
倘若我們發送的不僅僅是簡單文本,而是其他信息呢?比如:一條包含若干整型、實型、字符串等信息的數據,一條關于畫面切換、腳本執行的指令文本。盡管依然可以通過一個數據庫點的DESC參數進行傳遞,可是在接收端如何將所接收到的信息按期望的格式解析呢?也許可以考慮再創建若干數據庫點,每個數據庫點只傳遞一個數據,這樣一來又帶來新的問題:無法預知數據的個數、格式,解析這些數據也會帶來大量腳本編寫工作;如果是多個客戶端間通訊,那么上面所說的工作將要重復的次數=從m個客戶端中取出2個客戶端的組合個數,例如:從3個客戶端中取出2個客戶端的組合個數為3、從10個客戶端中取出2個客戶端的組合數是50。那么這將是一項令人望而卻步的工作。另外,新增的數據庫點無疑對項目成本來說是個挑戰。
有沒有一種手段,可以不使用數據庫點就能實現客戶端間數據通信,而且傳遞的數據以規范的形式發送和接收,并提供方便的解析方法?答案是:有。紫金橋軟件6.5版本新增的會話組件就可以專門解決這類問題。
簡介
會話組件是一種實現客戶端之間通訊的窗口組件。它通過同一數據網絡中的某個DB作為通訊中介,在不同客戶端之間實現異步數據通信,其運行的一般原理圖如下。

會話組件運行在客戶端的窗口中,而db.exe僅僅作為數據通信的中介。上圖中帶箭頭的直線代表數據流向,其中紅色的直線及虛線表示了客戶端A發送給客戶端B的數據走向情況,藍色的直線及虛線則表示了客戶端B發送給客戶端A的數據走向情況。在這個數據網絡中,任何客戶端之間都可以使用會話組件進行數據通信。
概念介紹
客戶端:指view.exe或infoview.ocx(IE客戶端)。
通信組:在一個網絡中所有需要相互通信的客戶端組成了一個通信組。這個網絡可以是以太網網絡,可以是串口網等。通信組中的任何一個成員均可以和組中其他成員進行數據通信。通信組可以交叉,即一個客戶端可以同時為兩個通信組中的成員。
會話名:在一個通信組中,每個會話組件對象在通信時使用的唯一標識。
中介節點:在一個通信組中,為所有成員客戶端提供通訊媒介的網絡節點。同一個組中的所有客戶端的中介節點必須指向該網絡中的同一個節點。這個節點可以是這個網絡中的任意一個有DB.exe運行的節點,該節點所在計算機中的客戶端可以不參與數據通信。
具體實現
1.
配置中介數據源
選定中介節點后,在需要進行數據通信的客戶端中建立指向中介節點的數據源,如果本機恰好為中介節點,那么使用“本地”數據源就可以了。
2.
創建組件對象
進入客戶端工程的組態環境中,創建一個窗口,然后打開子圖選擇畫面,找到“組件、復雜精靈/高級”選項卡,雙擊“會話組件”圖標,一個會話組件被創建在當前窗口中,將其命名。
3.
配置組件對象
雙擊組件,出現配置界面,如下圖所示:

在“數據源”處選擇事先指定的中介數據源。
在“自身名稱”處填寫本會話組件對象的會話名。
在“對方名稱”處填寫當前發送數據的目標會話組件對象的會話名。
4.
數據發送
數據發送的是通過會話組件的提供的兩個函數來實現的:
BOOL Send(String FuncionName,
ObDataTable Tab)
BOOL SendTo(String DestName,
String FuncionName, ObDataTable
Tab)
這兩個函數的功能是向目標客戶端發送一條信息,其中參數Tab為ObDataTable 類型的對象指針,Tab中包含了本次發送的所有信息。參數DestName為指定的目標客戶端的會話名。也就是說,如果使用函數Send則目標客戶端為組態時指定的客戶端,如果使用函數SendTo則可以動態指定目標客戶端。
參數FuncionName為目標客戶端會話組件所在窗口的自定義函數名,這個函數是回調函數,當目標客戶端收到這條信息后會自動調用這個窗口函數。其函數形式規定為:
void FuncName(String SrcName,
ObDataTable& Tab)
其中參數SrcName為本條信息的發送客戶端的會話名,Tab為發送的內容。
5.
數據接收
數據接收是通過上述回調函數來處理的。在接收端會話組件對象所在窗口中創建回調函數,注意回調函數的名字及參數類型一定要與規定一致。用戶可以在回調函數體內編寫收到信息后的處理動作。
在一個雙向數據通信的結構體系中,一個客戶端既是數據發送端同時也是數據接收端,所以每個客戶端都要實現數據發送和數據接收。
進階
1.
會話組件對象與客戶端
會話組件的本質是窗口組件,這就意味著同一客戶端中可以創建多個會話組件對象,但是每個會話組件對象應該擁有唯一的會話名。可以通過讓這些會話組件對象指向不同中介數據源,來實現與不同通信組成員客戶端的通訊。
2.
動態切換中介數據源
假設在組態時指定了會話組件的中介數據源為DS1,那么在運行時可以通過調用數據源函數SetNetAddr來動態切換其指向的網絡結點,從而切換中介數據源。
3.
如何發送廣播
通過會話組件提供的函數void GetUserNames(String Array Names),可以在運行時得到當前通信組中所有通信成員的會話名,然后針對所有會話名發送信息以便達到廣播的目的。
4.
通過會話組件能傳遞哪些數據
從會話組件的發送及回調函數來看,數據是通過數據表對象(ObDataTable)來傳遞的,ObDataTable是一種比較實用的表格,可以同時傳遞多行多列的文本、數值等數據,但是無法直接傳送文件。
5.
關于超時
因為涉及網絡通信,所以在網絡狀況較差甚至是斷開的情況下無法保證數據通信的暢通性和及時性,因此需要自行處理發送超時。一般在接收到數據后應該馬上返回一條信息告知發送端本條數據已經成功接收,如果發送端沒有在規定時間內收到反饋信息,則認為是超時。