Lotus C API Extension Manager 應用舉例
本文對 Lotus C API 中的 Extesnsion Manager 進行了探討,並用一個應用工程例項對 Extension Manager 的使用和設計過程進行了詳細的說明。閱讀本文,需要具有基本的 Lotus C API 程式設計經驗以及多執行緒和 Socket 程式設計概念。
Extension Manager 是 Lotus C API 提供的一個功能非常強大的設計機制,它允許應用程式設計者向 Notes/Domino 系統註冊自己感興趣的事件,例如 EM_NSFDBCLOSESESSION、EM_NSFDBCLOSE 等。從而在 Notes/Domino 進行核心操作之前(或者之後,取決於在事件註冊中使用的是 EM_REG_BEFORE 還是 EM_REG_AFTER)來執行自己設計的特製外掛程式。
Extension Manager 外掛程式的設計框架要符合一定的規則,這樣才能被 Notes/Domino 系統在合適的時機呼叫。關於Extension Manager 的詳細設計方法,請參考隨 Lotus C API 一起釋出的設計文件,基本上來講,一個具備基本功能的 Extension Manager 外掛程式應該具備以下幾個要素:
- DLL 入口函式:
Extension Manager 外掛程式必須被編譯為可執行的程式庫(例如,Windows 系統的動態連結庫 dll 或者是 UNIX 系統的 shared object)。程式庫的結構和命名規則是跟平臺相關的,詳細資訊請參考 Lotus C API 使用者手冊第十二章第二節:"Platform-Specific Naming Conventions" 。在 DLL 入口函式中,應當完成外掛程式例項的建立和釋放,並且負責在外掛程式退出之前,登出向 Notes/Domino 系統註冊的 EM_XX 事件。 - 外掛程式入口函式
該函式是定製外掛程式的入口函式,EM事件的註冊過程將會在此函式中加以實現。該函式宣告格式如下所示
STATUS LNPUBLIC MainEntryPoint (void);
該入口函式的名字可任意給定,但是必須在模組定義檔案(.def檔案)中將其宣告為匯出函式(EXPORTS function),並且匯出序號為1。
例子:
LIBRARY nextmngr INITINSTANCE EXPORTS MainEntryPoint @1
在註冊回掉函式之前,推薦使用 EMCreateRecursionID() 函式,這樣可以防止一個外掛程式被多次呼叫。 - 外掛程式回撥函式
該函式是 Extension Manager 外掛程式的業務處理函式,負責在收到註冊事件通知後進行定製處理。
要想執行一個定製的 Extension Manager 程式,需要做兩件事情:
- 將編譯成功的 DLL 檔案放在 Notes/Domino 的主目錄下
- 修改 notes.ini 檔案,增加一個變數如下所示
EXTMGR_ADDINS=NEXTMNGR
如果有多個外掛程式,在外掛程式名之間用逗號格開。如果多個外掛程式註冊了同一個事件,則按照 notes.ini 檔案中的外掛程式的註冊順序來依次進行處理。
在瞭解了以上基礎知識之後,我們將以 Windows 平臺為例,給出一個簡單而典型的 Extension Manager程式結構,本示例程式只是用來說明 Extension Manager 的程式架構和處理邏輯,不能編譯執行,具體的 Extension Manager 示例程式,請參考隨 Lotus C API 一起釋出的 Sample。
Extension Manager程式結構示例
/* Extension Manager程式結構示例*/ /*system header file*/ #include |
接下來,本文將介紹 Extension Manager 的一個工程例項,並希冀由這個工程例項對 Lotus C API 應用程式開發者在使用 Extension Manager 實現定製應用程式時給予一定的啟發和指導。
1) 工程背景:
某客戶為了加強內部辦公環境的管理,需要強制使用者加入 Windows 特定域。客戶希望採取繫結郵件系統訪問的方式:即限制使用者只有登入 Windows 域後才可以訪問郵件系統。
2) 工程設計:
為實現客戶需求,我們可以設想在客戶端部署一個 EM 程式。該客戶端 EM 程式註冊 EM_GETPASSWORD 事件,在Notes彈出密碼輸入對話方塊之前判斷當前 Windows 使用者是否在域中,如果不在域中就返回 ERR_BSAFE_USER_ABORT,這樣可以阻止 Notes 客戶端連線 Domino Server。程式片斷請參考 Extension Manager 程式結構示例。
一切進行的很順利,似乎工作到此已經萬事大吉了。然而且慢,如果仔細考慮一下,這種方案是不可取的,如果客戶端不安裝這個EM程式怎麼辦?或者如果使用者解除安裝這個 EM 程式的話怎麼辦?這樣的話客戶端完全可以繞開認證過程。
所以我們必須考慮在伺服器端進行統一的控制,這就需要在伺服器端也部署一個 EM 程式。該伺服器 EM 程式註冊 EM_SECAUTHENTICATION 事件,對每位向郵件伺服器傳送訪問請求的使用者進行實時授權鑑別,只有在客戶端登入 Windows 域的情況下,伺服器端 EM 程式才開啟該使用者訪問郵件伺服器的限制。
現在的問題是伺服器端 EM 程式如何鑑別來訪客戶端是否在 Windows 域中?答案是 Socket 通訊方法:客戶端 EM 程式在經過相關判斷之後,把 Notes 使用者的資訊寫入到安裝 Domino Server 的伺服器的某個檔案(如Info.DAT)中,伺服器端 EM 程式在認證來訪 Notes 使用者的時候查詢該檔案,如果發現來訪 Notes 使用者資訊在 Info.DAT 檔案中存在,則授權該使用者訪問郵件伺服器,否則則拒絕其訪問。
系統的整體架構如下圖所示:
圖一 系統整體架構
3) 模組設計與實現
系統分為三個元件,分別是:
-
Notes 客戶端 EM 元件
功能說明:負責判斷當前 Notes 使用者的 Windows 域資訊,並把相關資訊傳送給通訊伺服器,在接收到通訊伺服器的確認資訊之後,更新登陸時間窗資訊。(時間窗是一個時間段,某 Notes 客戶端在域中登陸 Domino Server 之後,允許在時間窗內該 Notes 客戶端不登陸域也能訪問郵件伺服器)
演算法如下:
I. 捕獲 EM_GETPASSWORD 訊息
II. 讀取登錄檔的內容,取得當前時間跟登錄檔中上一次登記的時間做比較,判斷時間窗是否過期。
III. 如果時間窗未過期,即該 Notes 客戶端已經在指定時間段內向 Server 註冊過了,則直接返回 ERR_EM_CONTINUE. 把控制權交給 Notes,允許其連線郵件伺服器。
IV. 如果時間窗過期,判斷當前 Windows 使用者否在域中,如果在域中,從登錄檔中讀取通訊伺服器的 IP 和埠,把 Notes User 的資訊傳送過去,然後等待 Server 的響應。如果收到 Server 的響應,那麼更新登錄檔中日期表項
V. 如果當前 Windows 使用者不在域中,說明在時間窗之內沒有人在域中登陸過 Domino Server,返回 ERR_BSAFE_USER_ABORT 阻止 Notes 連線郵件伺服器。
-
Domino 伺服器端 EM 元件
功能說明:捕獲當前試圖連線自己的 Notes 使用者,讀取使用者資訊檔案,判斷該當前使用者是否為合法使用者,從而決定是否授權該使用者訪問郵件伺服器。
演算法如下:
I. 註冊 EM_SECAUTHENTION 事件
II. 在事件發生時獲取當前申請連線的使用者名稱字
III. 查詢使用者資訊檔案,若有跟當前使用者匹配的資訊,說明該使用者是合法使用者,返回 ERR_EM_CONTINUE 將控制權交給 Domino Server。否則,返回 ERR_SECURE_FAILED_AUTH,拒絕該使用者的連線請求。
-
通訊伺服器程式
功能說明:負責讀取所有客戶端傳送給自己的使用者名稱資訊,儲存在使用者資訊檔案中。以備 Domino Server 側的 EM 程式訪問。
詳細設計以及說明,請參見通訊伺服器架構圖以及其說明。
I. 通訊伺服器架構圖
圖二 通訊伺服器架構圖
II. 說明:
該通訊伺服器是一個多執行緒併發程式,具備了四個模組,分別是:
a) 處理伺服器模組
功能說明:負責整個通訊伺服器程式的啟動和中止,並記錄整個系統的 Log 資訊b) 訊息件模組
功能說明:該模組由處理伺服器模組啟動,在啟動的時候啟動了三個執行緒,分別是:- 接收訊息執行緒
該執行緒啟動通訊模組,並等待通訊模組的訊息,如果通訊模組通知該執行緒有訊息到達,那麼去獲得該訊息並寫入接收訊息佇列裡面 - 處理訊息執行緒
該執行緒實時監測接收訊息佇列裡面是否有資料,如果有資料,那麼取出該資料,並寫入使用者資訊檔案裡面,寫入成功後,傳送一個 UDP 訊息到傳送訊息佇列裡面,UDP 訊息包括某個客戶端的 IP,埠以及確認訊息。其定義為:
struct UDPDATA{ unsigned long ulIPAddr; unsigned short wPort; string sData; };
- 傳送訊息執行緒
該執行緒實時監測傳送訊息佇列裡面是否有資料,如果有資料那麼取出來進行分析,獲得 IP 和埠,然後通過通訊模組把資料傳送出去。
c) 通訊模組
功能說明: 該模組封裝了 Socket 通訊的 API,完成網路通訊功能。d) 訊息佇列模組
功能說明: 該模組實現了 Message Queue 的功能,是一個雙向連結串列。目的是為了資料的快取,防止使用者資料丟失的可能性。系統有兩個訊息佇列,一個是接收訊息佇列,負責儲存接收的訊息;另外一個是傳送訊息佇列,負責儲存傳送的訊息。 - 接收訊息執行緒
Lotus C API 是一個強大的 Notes/Domino 二次開發工具,而 Extension Manager 更是其中極為重要而又極為複雜的一部分,通過這個工程例項,讀者可以對此有一定的認識。今後,我們將繼續為讀者進行有關 Extension Manager 的專題介紹。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14751907/viewspace-444280/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle resource manager (ORM)舉例OracleORM
- SQLLOAD應用舉例SQL
- 利用Lotus Connections API製作桌面應用API
- 利用 Lotus Connections API 製作桌面應用API
- 設計模式應用舉例設計模式
- golang Context應用舉例GolangContext
- oracle rollup,cube子句的應用舉例;Oracle
- AC-DMIS測量程式應用舉例
- 並查集(Union-Find) 應用舉例並查集
- WebSphere Remote Server 簡介及其應用舉例WebREMServer
- Lotus Notes/Domino 的C API程式設計API程式設計
- beegoapix - beego api extensionGoAPI
- 在 Lotus Notes 複合應用中整合 Lotus Symphony
- Lotus Domino/Notes Toolkits綜述(二) C API (轉)API
- 正規表示式理解及簡單應用舉例
- 樂觀鎖與悲觀鎖及應用舉例
- 再談多型--多型的應用舉例: (轉)多型
- R語言中管道符號 %>% 的應用 及 舉例R語言符號
- C#中類的使用舉例C#
- 並查集(Union-Find) 應用舉例 --- 基礎篇並查集
- 輕鬆搭建基於 Serverless 的 Go 應用(Gin、Beego 舉例)ServerGo
- Python偏函式應用舉例-路燈指示牌Python函式
- mssql sqlserver in 關鍵字在值為null的應用舉例SQLServerNull
- 常用的Linux可插拔認證模組(PAM)應用舉例Linux
- Android底層字元傳遞給上層應用舉例Android字元
- 執行緒池的實現原始碼及應用舉例執行緒原始碼
- C# 程式碼效能優化舉例C#優化
- Object-c KVC的使用和舉例Object
- iOS Extension擴充套件開啟宿主應用iOS套件
- c++介面定義及實現舉例C++
- 自定義構建互動式SSH應用程式,用Python為大家舉例Python
- Java在量化投資等金融業的關鍵應用舉例 - oracleJavaOracle
- sysconf()函式應用舉例:檢視CPU及記憶體資訊函式記憶體
- oracle rollup,cube子句的應用舉例(可以實現總計,小計)Oracle
- The MySQL C API程式設計例項MySqlAPI程式設計
- zabbix 操作 API 用例小記API
- 裝飾模式在jsp tag extension中的應用模式JS
- uva 11997 priority_queue 應用舉例(超省時間!!!)