【腾讯通服务器的消息集成解决方案】之与勤哲Excel服务器的集成
本著懶人的原則,提供最簡單的解決方案!Let's go~~(文中采用的RTX版本為3.61,ES版本為7.1.7)
方案思路:
1.首先做一張數據表來存儲消息隊列,并利用RTX的SDK寫一個程序來每隔一段時間從該表中取出消息隊列發送出去;
2.然后為ES的ESSys數據庫里面存儲待辦工作流信息的數據表寫一個觸發器,讓它有新增數據的時候自動往1樓的表里面寫入消息隊列。
設計方案:
1.首先要解決RTX帳號和ES帳號的映射問題。很簡單,在RTX和ES里面新建用戶的時候,帳號不都是可以手工定義的嘛,就統一用員工工號唄~
如果兩個系統都已經有帳號了,而且還是不統一的,那就改ES里面的帳號吧,把它向RTX統一。(推薦做法)
如果覺得更改ES的帳號對用戶影響太大,還要另發通知,那就不改帳號,把手機或電子郵件改成RTX帳號吧~~(懶人嘛)
2.接下來做消息隊列的數據表,為了配置權限簡單,就單獨建一個數據庫<RTX>吧,然后在數據庫中建一個數據表<MSG_Queue>,數據字典如下:
| 列名 | 數據類型 | 長度 | 允許空 | 默認值 | 說明 |
| MsgID | bigint | 8 | 主鍵。自動編號。 | ||
| DelayTime? | smallint | 2 | √ | 0 | 消息框在桌面停留時間(秒),默認為手動關閉。 |
| Receiver | varchar | 20 | 接收者,用戶名稱或號碼。 | ||
| MsgInfo | varchar | 500 | 消息提醒內容。 | ||
| Title | varchar | 10 | √ | 消息提醒標題。(建議5個漢字的寬度以內) | |
| AssType | tinyint | 1 | √ | 0 | 保留。 |
| Type | tinyint | 1 | √ | 0 | 消息提醒類別。0:普通消息,1:緊急消息。 |
| SendMode | tinyint | 1 | √ | 0 | 發送模式。0:普通模式,1:發送給所有人。 |
?
再創建一個獨立的SQL帳號RTX,密碼也是RTX,配置權限為可以讀寫數據表<MSG_Queue>,這個帳號用來在RTX接口程序中使用。
3. 開始寫RTX接口程序。我用記事本寫的VBS腳本,懶得配置軟件開發環境,也不用編譯,修改起來簡單,充分體現開源精神!(懶人嘛)
不羅嗦,直接貼代碼,有問題請教SDK~
?1'********************************************************************
?2'Author:?碟子?http://cancelpj.cnblogs.com/
?3'Date:?2008-02-17
?4'Detail:?定時從數據庫取得消息隊列,并調用RTX接口發送即時消息提醒。
?5'********************************************************************
?6
?7'循環周期(分鐘)
?8Const?CycleTime?=?1
?9'日志文件
10Const?LogFile?=?"RTX_Notify.log"
11'追加寫入模式
12Const?ForAppending?=?8
13
14Dim?RTXObj,?RTXParams
15Dim?RTXResult
16Dim?objFSO,?objLogFile
17Dim?cnSrc,?rst
18
19Set?RTXObj?=??CreateObject("rtxserver.rtxobj")
20Set?RTXParams?=?CreateObject("rtxserver.collection")
21RTXObj.Name?=?"SYSTOOLS"
22
23Set?objFSO?=?CreateObject("Scripting.FileSystemObject")
24set?cnSrc?=?CreateObject("ADODB.Connection")
25set?rst?=?CreateObject("ADODB.RecordSet")?
26
27While?1
28????cnSrc.Open?"Provider=sqloledb;server=RTX數據庫地址;Uid=rtx;Pwd=rtx;Database=RTX"
29????set?rst?=?cnSrc.Execute?_
30????????("SELECT?MsgID,DelayTime,Receiver,Title,MsgInfo,Type,SendMode?FROM?Msg_Queue")
31
32????Set?objLogFile?=?objFSO.OpenTextFile(LogFile,?ForAppending,?True)
33
34????Do?until?rst.eof
35????????'Wscript.StdOut.WriteLine(rst("now()?&?VBTAB?&?MsgID?:?"?&?rst("MsgID")?&?VBTAB?&?rst("Title")?&?VBTAB?&?rst("MsgInfo"))
36????????RTXParams.Remove?"SENDMODE"
37
38????????'RTXParams.Add?"MSGID",?rst("MsgID")
39????????'RTXParams.Add?"ASSTYPE",?"0"
40????????RTXParams.Add?"DELAYTIME",?rst("DelayTime")*1000
41????????RTXParams.Add?"USERNAME",?rst("Receiver")
42????????RTXParams.Add?"TITLE",?rst("Title")
43????????RTXParams.Add?"MSGINFO",?rst("MsgInfo")
44????????RTXParams.Add?"TYPE",?rst("Type")????'0?-?普通消息;1?-?緊急消息
45
46????????iSendMode?=?0
47????????if?rst("SendMode")?=?1?then
48????????????iSendMode?=?iSendMode?+?&H1????'發送給所有用戶
49????????end?if
50????????if?iSendMode?>?0?then?
51????????????iSendMode?=?iSendMode?+?&H10????'需要查詢狀態
52????????????RTXParams.Add?"SENDMODE",?iSendMode
53????????end?if
54???????
55????????On?error?resume?next
56????????RTXResult?=?""
57????????RTXResult?=?RTXobj.Call2(&H2100,?RTXParams)?
58????????if(?err.number?<?0)?then?
59????????????objLogFile.Write?now()?&?VBTAB?&?err.Description
60????????????objLogFile.Write?VBTAB?&?"MsgID?:?"?&?rst("MsgID")?&?VBTAB?&?rst("Title")
61????????????objLogFile.Write?VBTAB?&?rst("MsgInfo")
62????????????objLogFile.Write?VbCrLf
63????????else?
64????????????objLogFile.Write?now()?&?VBTAB?&?"發送成功"
65????????????objLogFile.Write?VBTAB?&?"MsgID?:?"?&?rst("MsgID")?&?VBTAB?&?rst("Title")
66????????????objLogFile.Write?VBTAB?&?rst("MsgInfo")
67????????????objLogFile.Write?VbCrLf
68????????????
69????????????cnSrc.Execute?"DELETE?FROM?Msg_Queue?WHERE?MsgID="?&?rst("MsgID")
70????????????'rst.Delete
71????????????Wscript.Sleep?10*1000
72????????end?if
73????????
74????????rst.MoveNext
75????Loop
76
77????set?rst?=?Nothing
78????cnSrc.close
79????objLogFile.Close
80????Wscript.Sleep?CycleTime*1000*60
81WEnd
腳本需要在RTX服務器上運行,且SDK Server服務必須啟動。(推薦做法)
如果在其它計算機上運行腳本,需要安裝RTX的SDK,配置SDK安裝目錄下RTXServerAPI.ini中RTX服務器的IP地址,還要修改RTX SDK Server的IP限制(修改RTX服務器安裝目錄下 SDKProperty.XML)。
OK,改完了配置就把服務重啟一下,然后往消息隊列表隨便寫點什么內容,測試一下腳本運行是否正常,再歇一會兒~~
4.開始寫觸發器。打開查詢分析器,登陸到ES數據庫,選中ESSys數據庫,然后執行以下SQL腳本。
FG_TR_MessageQueue?1?IF?EXISTS?(SELECT?name?
?2????????FROM???sysobjects?
?3????????WHERE??name?=?N'FG_TR_MessageQueue'?
?4????????AND???????type?=?'TR')
?5?????DROP?TRIGGER?FG_TR_MessageQueue
?6?GO
?7?
?8?CREATE?TRIGGER?FG_TR_MessageQueue
?9?ON?CFWiTodo
10?AFTER?INSERT
11?AS?
12?/***********************************************
13?Author:?碟子?http://cancelpj.cnblogs.com/
14?Date:?2008-02-17
15?Description:?當Excel服務器產生新的工作流待辦事宜時,
16?????將信息發送到RTX消息隊列。
17?***********************************************/
18?BEGIN
19?
20?DECLARE???@Receiver???VarChar(20)??
21?DECLARE???@MsgInfo???VarChar(500)??
22???
23?--獲取接收人的RTX號,以及待發送的消息內容。
24?SELECT?@Receiver?=?u.MobilePhone,
25?/**
26?????p.pName+'_'+t.tName?as?[任務],
27?????case?wi.state1
28?????when?2
29?????????then?isnull(wi.untreadName,wi.creByName)
30?????else?wi.creByName
31?????end?as?[交辦人],
32?????convert(smalldatetime,case?wi.state1
33?????when?2
34?????????then?isnull(wi.UntreadTime,wi.creDate)
35?????else?wi.creDate?
36?????end,120)?as?[交辦時間],
37?**/
38?????@MsgInfo?=?case?wi.state1
39???????when?1
40???????????then?N'暫存:'
41???????when?2
42???????????then?N'被退回:'
43???????else?''
44???????end?+?'
45?任務:'+
46?????p.pName+'_'+t.tName?+?'
47?交辦人:'+
48?????case?wi.state1
49?????when?2
50?????????then?isnull(wi.untreadName,wi.creByName)
51?????else?wi.creByName
52?????end?+?'
53?交辦時間:'+
54?????convert(nvarchar,case?wi.state1
55?????when?2
56?????????then?isnull(wi.UntreadTime,wi.creDate)
57?????else?wi.creDate?
58?????end,120)
59?????--?+?wi.wiDesc
60?FROM?CFWorkitems?wi,?CFTasks?t,?CFwiTodo?a,?CFProcesses?p,?Users?u,?Inserted?i?
61?WHERE?u.UserID?=?a.userId?and?wi.wiId?=?a.wiId?--and?wi.tId=t.tId?and?wi.pId=p.pId?
62?????and?t.tType<>3?and?wi.state?=0?and?a.userId?=?i.userId
63?ORDER?BY?(case?wi.state1?when?2?then?isnull(wi.Untreadtime,wi.creDate)?else?wi.creDate?end)?desc?
64?
65?
66?--由于ES本身在存儲表單數據的過程中使用了事務,再在觸發器中操作遠程數據庫就會引起【嵌套事務】。
67?--以上是個人猜測,未經證實;以下是針對“無法在此會話中啟動更多的事務”的解決方法。
68?--用于?SQL?Server?的?Microsoft?OLE?DB?提供程序不支持嵌套事務。
69?--因此,對于隱性或顯式事務的內部數據修改操作和分布式分區視圖上的數據修改操作,
70?--應將?XACT_ABORT?設置為?ON。
71?SET?XACT_ABORT?ON
72?
73?--用觸發器修改遠程數據的兩種方式。
74?--方式一:較安全,配置較復雜。
75?--????需要在源數據庫服務器建立一個指向目標服務器的鏈接服務器,
76?--????登陸方式保存在鏈接服務器中,不會在觸發器中顯示,比較安全。
77?/**
78?INSERT?INTO?[RTX數據庫地址].RTX.dbo.Msg_Queue(Receiver,Title,MsgInfo)?
79?????VALUES(@Receiver,'Excel服務器消息提醒',@MsgInfo)???
80?**/
81?--方式二:不安全,無需另外配置。
82?INSERT?INTO?OPENDATASOURCE('SQLOLEDB','Data?Source=RTX數據庫地址;User?ID=rtx;Password=rtx'
83?????).RTX.dbo.Msg_Queue(Receiver,Title,MsgInfo)?
84?????VALUES(@Receiver,'消息提醒','Excel服務器消息提醒
85?'+@MsgInfo)???
86?
87?END
88?
89?GO
90?
91?--設置該觸發器為最后執行
92?EXEC?sp_settriggerorder?'FG_TR_MessageQueue','Last','Insert'
由于我的RTX數據庫和ESSys數據庫不在同一臺服務器上,因此SQL腳本中涉及到用觸發器修改遠程數據庫的問題,需要對服務器的MDTC安全選項進行配置;如果在同一臺數據庫上那就不需要了,簡單修改一下SQL腳本的相關代碼就可以。
MSDTC安全選項的配置如果不對,在ES中保存工作流表單時就會出現“新事務不能登錄到指定的事務管理器中”的錯誤。我的配置方式如下圖,安全性低,不推薦模仿,僅供參考。
管理工具—— 組件服務——我的電腦——屬性
源服務器(ESSys所在的服務器)
?
目標服務器(RTX數據庫所在服務器)
如果設置為“要求對雙方進行驗證”,那么安全性就有保障了,不過我不知道在這種情況下DTC登陸帳戶應該如何設置,萬望高手賜教!!
?
OK,基本上大功告成了,江湖慣例,上效果圖~
?相關代碼下載:SendNotify_V1_fix.rar (最近發現消息不能群發所有人,原來是SendNotify.vbs中關于iSendMode的處理參數寫錯了,請重新下載,抱歉抱歉~)
?
PS:老大說我的這個設計架構對RTX服務器的耦合度太高,應該讓RTX服務器對其它應用服務器透明,所有配置只在RTX服務器這邊完成,其它應用服務器只提供各自的消息隊列表,我覺得蠻有道理的,不過那樣就不能用腳本來寫程序了,所有應用服務器的后臺數據庫密碼要明文寫在腳本里面太不安全了,過段時間用其它語言寫一個像模像樣的程序吧,最好還是運行后在桌面右下角有圖標的~~
?
拋磚引玉,如果看官從中獲得了一點點啟發,那我就很欣慰了,如果你把我后面想做的事都做了,就把代碼發我一份吧~~ (懶人嘛)
轉載于:https://www.cnblogs.com/cancelpj/archive/2009/02/17/1392425.html
總結
以上是生活随笔為你收集整理的【腾讯通服务器的消息集成解决方案】之与勤哲Excel服务器的集成的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 笔记“SQL与Access”
- 下一篇: eigrp ospf 邻居建立过程比