喬富強,趙 旭
(天津中德職業技術學院 信息系,天津 300350)
在能源信息化集成過程中,環保局要求各熱電廠的鍋爐實時數據進行上傳,企業內部也需要通過瀏覽器實時監控鍋爐數據。這些數據的傳輸從起點到終點要經過現場工控機(配有OPC服務器)、OPC客戶端、UDP傳輸層和監控主機,其中OPC客戶端為分散于各處的生產數據與中央監控搭建了橋梁。大部分熱電廠都通過配置OPC服務器,向外提供符合OPC標準的統一接口[1],但傳統的OPC客戶端都是基于一個客戶端訪問一臺服務器開發的[2-3]。為了適應環保局對多個熱電廠數據的同時采集,本系統實現了單一客戶端對多服務器的連接。同時考慮到每個連接應獨立工作,當一個連接出現問題,不影響其它服務器的訪問,采用了多線程模型解決這一問題。另外,數據采集是長期的工作,由于網絡環境的不穩定性,客戶端與服務器的連接經常斷開,因此,系統提供了自動監控連接狀態,斷點續連的功能,減少了操作人員的負擔。
OPC(OLE for process control)是一個用于過程控制的技術標準,它基于微軟的OLE(現在的Active X)、COM(部件對象模型)和DCOM(分布式部件對象模型)技術,采用客戶/服務器模式,制定了關于數據采集、歷史趨勢以及事件報警等接口標準[4]。只要遵守這些標準,在客戶機和服務器之間就可以交換數據。
OPC邏輯對象模型中包括3種對象:服務器對 象 (OPCServer)、 組 對 象 (OPCGroup) 和 項 對 象(OPCItem)。這3種對象層次不同,每種對象都包括一系列接口。如圖1所示,一個OPCItem對應實際的硬件裝置上的某一個channel或port,它包括值(Value)、品質(Quality)、時間戳(Time Stamp)3 個基本屬性;一個OPCGroup則包含了許多的OPCItem,同時也定義了這些OPCItem更新的時間、方式,并提供讀取OPCItem屬性的接口;而一個OPCServer則包含若干個OPCGroup,同時提供操作這些OPCGroup的接口[5]。OPC客戶端若要從服務器中采集數據,首先應得到服務器對象的引用,然后通過操作組對象的接口動態創建組對象,最后通過組對象讀取項對象的屬性值。

圖1 OPC服務器結構圖Fig.1 OPC server structure diagram
本系統以Visual Studio 2010為平臺,應用VB.Net語言開發,項目中引入了OPCAutomation.dll組件,其中封裝了客戶端與服務器交互的方法。
項目中建立了3個與功能相關的類,其中Opc-ClientOperator類主要表達了客戶端與服務器一對一的連接,并提供了采集數據方法;ThreadsOperator類封裝了OpcClientOperator類的對象數組,每個對象代表一個與服務器的連接,從而實現客戶端與多服務器的交互,這個類也定義了線程數組,它為每個連接啟動一個線程,避免了多連接情況下的相互沖突;OpcClientObserver類提供了異常處理以及修復連接的方法,當連接發生異常時,調用這些方法實現斷點續連。這3個類的主要成員如圖2所示,詳細介紹這些類的實現細節。

圖2 OPC客戶端類視圖Fig.2 OPC client class view
OpcClientOperator對象可完成對一臺OPC服務器的數據采集,其工作過程由以下步驟組成:
步驟1調用ConnectRemoteServer函數連接到指定的服務器,該函數以服務器IP地址或主機名作為參數,若連接成功,MyOpcServer變量保留服務器對象的引用,并用ServerState記錄服務器連通狀態(OPCServerState.OPCRunning),否則捕獲異常,提示錯誤信息。
步驟2調用CreateGroup函數創建組對象,MyOpcGroup保存組對象的引用,當成功創建了組對象,可添加即將被采集的項對象序列,其中組名稱及項變量名稱由項目的配置文件導入,關鍵語句如下:

步驟3調用SetGroupProperty函數設置組的屬性,主要包括下列內容:


步驟4采集數據,StartClientChannel是本類中的主要函數,也是啟動線程時的綁定函數,該函數內部首先執行了以上3個過程,然后開始從服務器采集數據,而本類定義了3種客戶端與服務器的通信方式:
①同步方式MyOPCGroup_SyncRead
OPC服務器把項對象的值、品質和時間戳作為函數的參數返回給客戶端,在結果被返回之前客戶端程序必須處于等待狀態。
②異步方式MyOPCGroup_AsyncRead
OPC服務器接到客戶端的請求后,幾乎立即將方法返回。OPC客戶端隨后可以進行其他處理。當完成數據訪問時,OPC服務器主動觸發客戶端的異步訪問完成事件,將數據訪問結果傳送給OPC客戶端。OPC客戶端在事件處理過程中接收傳來的數據。
③訂閱方式MyOPCGroup_DataChange
服務器按一定的更新周期(UpdateRate)更新數據緩沖區的數值時,如果發現數據有變化,就會觸發組對象的DataChange事件通知客戶端,而發生變化的數據作為事件處理函數的參數返回給客戶端。
步驟5啟動定時器timer,定期監測服務器連接狀態 CheckServerState,若連接異常,則觸發OffLine事件通知OpcClientObserver來處理。
為解決斷點續連問題,本系統采用了事件和委托機制[6],事件是對象發送的消息,以通知操作的發生。操作可能是由用戶交互引起的,也可能是由某些其他的程序邏輯觸發的。引發事件的對象稱為事件發送方。捕獲事件并對其作出響應的對象叫做事件接收方。這種機制源自于Observer(觀察者)模式,事件的發送方是被觀察的主體,事件的接收方是觀察者,當主體發生變化時,觀察者被自動告知更新[7]。在事件通信中,事件發送方不知道哪個對象或方法將接收并處理該事件。因此在發送和接收方之間必須存在一個媒介 (類似函數指針)。.NET Framework定義了一個特殊的類型–委托類型(Delegate),該類型提供函數指針的功能。委托是可保存對方法的引用的類,與其他的類不同,委托類具有一個簽名,并且它只能引用與其簽名匹配的方法。這樣委托就等效于一個類型安全的函數指針或一個回調。
根據事件和委托機制,首先在OpcClientOperator類中聲明了一個委托類型OffLineEventHandler,以及依托于該委托的事件OffLine,當觸發事件時,由該委托所指向的函數來處理。

其中參數sender表示引發事件的對象,而參數e中記錄了事件接收方感興趣的信息,比如服務器的連接狀態ServerState和地址等,接收方通過這些值判斷異常的類型以及重新連接的地址。
接下來在OpcClientObserver類中定義了3個函數,其中RepairConnection是符合OffLineEventHandler委托類型的事件處理函數,它先調用ExceptionHandle來判斷連接異常的類型,若為物理性斷網,則通知用戶手動操作,否則嘗試重新建立與Opc服務器的連接,若一次連接不成功,則等待若干秒后重新嘗試,反復幾次,其中等待時間和最大重連次數由用戶在ThreadWaitingTime和MaxConnCount成員變量中的賦值所決定。若連接成功則調用ThreadHandle恢復數據采集的線程;若達到最大重連次數仍未成功,則提示用戶手動操作,并結束數據采集線程。
.NET Framework允許用戶將事件與處理程序動態綁定,當主程序啟動后,分別為每個OpcClient-Operator對象綁定事件處理函數。

這樣,在對數據采集線程實施定時監控過程中,如果發現某個連接斷開,則引發OffLine事件,根據委托,操作系統自動調用事件處理函數重新建立連接。
該類封裝了OpcClientOperator類的對象數組ClientOp,和.Net線程數組 Threads。DoClientJob 是客戶端工作的啟動函數,它首先初始化ClientOp數組的每個對象,為每個對象設置連接服務器的地址,組信息及項信息,然后將這些對象的Start-ClientChannel函數分別綁定到Threads數組的每個線程對象,作為工作線程的函數,最后依次啟動這些線程。

每個線程獨立處理客戶端與一臺服務器的連接及數據采集工作,當一個連接異常時,不影響其它線程的工作[8]。
雖然本系統實現了斷點續連的功能,但在某些情況下,比如網絡物理性斷開,或重新連接數次達到上限都不成功,還是需要人員手工操作,基于這些考量,本類也提供了動態管理線程的方法。ResetOneThread函數用于重置某個指定的線程,當某個線程異常而中止工作時,可以調用該函數重新啟動這個線程。當客戶端不再需要訪問某個服務器時,可以調用StopOneThread函數停止某個指定的線程,它們以服務器地址和線程對象的下標為參數。OPC客戶端完整的工作流程如圖3所示。

圖3 OPC客戶端工作流程圖Fig.3 OPC client working flow chart
系統測試工作在一個真實的環境下進行,應用該OPC客戶端采集天津市濱能集團5組鍋爐的參數,首先在各自的工控機上搭建OPC服務器環境,應用的服務軟件是西門子的WinCC。然后設置組和項的參數,并將這些參數導出到配置文件供OPC客戶端使用,這些參數包括OPC服務器地址、類型、組名、項變量名以及相關注釋。最后在一個遠程主機上啟動客戶端,開始訪問這5個OPC服務器。
配置客戶端的操作如圖4所示,列表框中導入了所有服務器的地址,當選擇某個地址時,文本框中會顯示該服務器類型和已添加的組。當點擊“導入參數項”時,系統會讀取配置文件中的項變量信息,包括序號、變量名和標題。啟動客戶端以后開始采集所有服務器的項變量數據。

圖4 配置OPC客戶端Fig.4 Configure OPC client
在列表中選擇某個服務器地址,可以查看從該服務器上接收的項變量的值、質量和時間戳信息。通過“重置線程”和“終止線程”,用戶可以手動的重啟或停止當前線程,而不影響另外4個線程的采集工作。當重啟某個OPC服務器時,連接發生異常,此時斷點續連機制生效,經過數次的重連、等待,連接恢復,照常接收數據。
本系統通過OPC技術,采用面向對象封裝的思想,充分利用VB.NET的多線程機制進行多服務器的連接,動態地管理線程,提高了系統的穩定性,完成了企業鍋爐數據的采集與發送的開發。系統提供了便利的人機界面,方便了使用者的操作,在實際應用過程中達到了預期的效果。
[1]蔣近,段斌.基于OPC技術的監控主站實時數據傳輸[J].電力自動化設備,2008,28(9):97-100.
[2]黃錦花,常喜茂.基于快速開發工具的OPC客戶端的開發與實現[J].化工自動化及儀表,2013,40(7):893-897.
[3]蘇磊,李茜,湯偉.OPC數據訪問客戶端的研究與實現[J].計算機工程,2010,36(11):80-82.
[4]陳燁,倉小金,彭蓬,袁小平.基于OPC中問件技術的網絡控制系統[J].電力自動化設備,2011,31(1):100-104.
[5]望荊沙.基于OPC DA 3.0的OPC服務器與客戶端的研究與實現[D].西安:西安電子科技大學,2012.
[6]任玉輝,張新海.動態連接多服務器的OPC客戶端在燒結控制系統中的應用[J].燒結球團,2011,36(1):19-24.
[7]James W.Cooper.C#設計模式[M].北京:科學出版社,2011.
[8]Gastón C.Hillar.C#并行編程高級教程:精通NET 4 Parallel Extensions[M].北京:清華大學出版社,2012.