【腾讯通服务器的消息集成解决方案】之与勤哲Excel服务器的集成
2009-02-17 16:09
232 查看
本着懒人的原则,提供最简单的解决方案!Let's go~~'********************************************************************
2'Author: 碟子 http://cancelpj.cnblogs.com/
3'Date: 2008-02-17
4'Detail: 定时从数据库取得消息队列,并调用RTX接口发送即时消息提醒。
5'********************************************************************
6
7'循环周期(分钟)
8Const CycleTime = 1
9'日志文件
Const LogFile = "RTX_Notify.log"
'追加写入模式
Const ForAppending = 8
Dim RTXObj, RTXParams
Dim RTXResult
Dim objFSO, objLogFile
Dim cnSrc, rst
Set RTXObj = CreateObject("rtxserver.rtxobj")
Set RTXParams = CreateObject("rtxserver.collection")
RTXObj.Name = "SYSTOOLS"
Set objFSO = CreateObject("Scripting.FileSystemObject")
set cnSrc = CreateObject("ADODB.Connection")
set rst = CreateObject("ADODB.RecordSet")
While 1
cnSrc.Open "Provider=sqloledb;server=RTX数据库地址;Uid=rtx;Pwd=rtx;Database=RTX"
set rst = cnSrc.Execute _
("SELECT MsgID,DelayTime,Receiver,Title,MsgInfo,Type,SendMode FROM Msg_Queue")
Set objLogFile = objFSO.OpenTextFile(LogFile, ForAppending, True)
Do until rst.eof
'Wscript.StdOut.WriteLine(rst("now() & VBTAB & MsgID : " & rst("MsgID") & VBTAB & rst("Title") & VBTAB & rst("MsgInfo"))
RTXParams.Remove "SENDMODE"
'RTXParams.Add "MSGID", rst("MsgID")
'RTXParams.Add "ASSTYPE", "0"
RTXParams.Add "DELAYTIME", rst("DelayTime")*1000
RTXParams.Add "USERNAME", rst("Receiver")
RTXParams.Add "TITLE", rst("Title")
RTXParams.Add "MSGINFO", rst("MsgInfo")
RTXParams.Add "TYPE", rst("Type") '0 - 普通消息;1 - 紧急消息
iSendMode = 0
if rst("SendMode") = 1 then
iSendMode = iSendMode + &H1 '发送给所有用户
end if
if iSendMode > 0 then
iSendMode = iSendMode + &H10 '需要查询状态
RTXParams.Add "SENDMODE", iSendMode
end if
On error resume next
RTXResult = ""
RTXResult = RTXobj.Call2(&H2100, RTXParams)
if( err.number < 0) then
objLogFile.Write now() & VBTAB & err.Description
objLogFile.Write VBTAB & "MsgID : " & rst("MsgID") & VBTAB & rst("Title")
objLogFile.Write VBTAB & rst("MsgInfo")
objLogFile.Write VbCrLf
else
objLogFile.Write now() & VBTAB & "发送成功"
objLogFile.Write VBTAB & "MsgID : " & rst("MsgID") & VBTAB & rst("Title")
objLogFile.Write VBTAB & rst("MsgInfo")
objLogFile.Write VbCrLf
cnSrc.Execute "DELETE FROM Msg_Queue WHERE MsgID=" & rst("MsgID")
'rst.Delete
Wscript.Sleep 10*1000
end if
rst.MoveNext
Loop
set rst = Nothing
cnSrc.close
objLogFile.Close
Wscript.Sleep CycleTime*1000*60
WEnd
脚本需要在RTX服务器上运行,且SDK Server服务必须启动。(推荐做法)
如果在其它计算机上运行脚本,需要安装RTX的SDK,配置SDK安装目录下RTXServerAPI.ini中RTX服务器的IP地址,还要修改RTX SDK Server的IP限制(修改RTX服务器安装目录下 SDKProperty.XML)。
OK,改完了配置就把服务重启一下,然后往消息队列表随便写点什么内容,测试一下脚本运行是否正常,再歇一会儿~~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
AFTER INSERT
AS
/***********************************************
Author: 碟子 http://cancelpj.cnblogs.com/
Date: 2008-02-17
Description: 当Excel服务器产生新的工作流待办事宜时,
将信息发送到RTX消息队列。
***********************************************/
BEGIN
DECLARE @Receiver VarChar(20)
DECLARE @MsgInfo VarChar(500)
--获取接收人的RTX号,以及待发送的消息内容。
SELECT @Receiver = u.MobilePhone,
/**
p.pName+'_'+t.tName as [任务],
case wi.state1
when 2
then isnull(wi.untreadName,wi.creByName)
else wi.creByName
end as [交办人],
convert(smalldatetime,case wi.state1
when 2
then isnull(wi.UntreadTime,wi.creDate)
else wi.creDate
end,120) as [交办时间],
**/
@MsgInfo = case wi.state1
when 1
then N'暂存:'
when 2
then N'被退回:'
else ''
end + '
任务:'+
p.pName+'_'+t.tName + '
交办人:'+
case wi.state1
when 2
then isnull(wi.untreadName,wi.creByName)
else wi.creByName
end + '
交办时间:'+
convert(nvarchar,case wi.state1
when 2
then isnull(wi.UntreadTime,wi.creDate)
else wi.creDate
end,120)
-- + wi.wiDesc
FROM CFWorkitems wi, CFTasks t, CFwiTodo a, CFProcesses p, Users u, Inserted i
WHERE u.UserID = a.userId and wi.wiId = a.wiId --and wi.tId=t.tId and wi.pId=p.pId
and t.tType<>3 and wi.state =0 and a.userId = i.userId
ORDER BY (case wi.state1 when 2 then isnull(wi.Untreadtime,wi.creDate) else wi.creDate end) desc
--由于ES本身在存储表单数据的过程中使用了事务,再在触发器中操作远程数据库就会引起【嵌套事务】。
--以上是个人猜测,未经证实;以下是针对“无法在此会话中启动更多的事务”的解决方法。
--用于 SQL Server 的 Microsoft OLE DB 提供程序不支持嵌套事务。
--因此,对于隐性或显式事务的内部数据修改操作和分布式分区视图上的数据修改操作,
--应将 XACT_ABORT 设置为 ON。
SET XACT_ABORT ON
--用触发器修改远程数据的两种方式。
--方式一:较安全,配置较复杂。
-- 需要在源数据库服务器建立一个指向目标服务器的链接服务器,
-- 登陆方式保存在链接服务器中,不会在触发器中显示,比较安全。
/**
INSERT INTO [RTX数据库地址].RTX.dbo.Msg_Queue(Receiver,Title,MsgInfo)
VALUES(@Receiver,'Excel服务器消息提醒',@MsgInfo)
**/
--方式二:不安全,无需另外配置。
INSERT INTO OPENDATASOURCE('SQLOLEDB','Data Source=RTX数据库地址;User ID=rtx;Password=rtx'
).RTX.dbo.Msg_Queue(Receiver,Title,MsgInfo)
VALUES(@Receiver,'消息提醒','Excel服务器消息提醒
'+@MsgInfo)
END
GO
--设置该触发器为最后执行
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服务器这边完成,其它应用服务器只提供各自的消息队列表,我觉得蛮有道理的,不过那样就不能用脚本来写程序了,所有应用服务器的后台数据库密码要明文写在脚本里面太不安全了,过段时间用其它语言写一个像模像样的程序吧,最好还是运行后在桌面右下角有图标的~~
抛砖引玉,如果看官从中获得了一点点启发,那我就很欣慰了,如果你把我后面想做的事都做了,就把代码发我一份吧~~ (懒人嘛
)
2'Author: 碟子 http://cancelpj.cnblogs.com/
3'Date: 2008-02-17
4'Detail: 定时从数据库取得消息队列,并调用RTX接口发送即时消息提醒。
5'********************************************************************
6
7'循环周期(分钟)
8Const CycleTime = 1
9'日志文件
Const LogFile = "RTX_Notify.log"
'追加写入模式
Const ForAppending = 8
Dim RTXObj, RTXParams
Dim RTXResult
Dim objFSO, objLogFile
Dim cnSrc, rst
Set RTXObj = CreateObject("rtxserver.rtxobj")
Set RTXParams = CreateObject("rtxserver.collection")
RTXObj.Name = "SYSTOOLS"
Set objFSO = CreateObject("Scripting.FileSystemObject")
set cnSrc = CreateObject("ADODB.Connection")
set rst = CreateObject("ADODB.RecordSet")
While 1
cnSrc.Open "Provider=sqloledb;server=RTX数据库地址;Uid=rtx;Pwd=rtx;Database=RTX"
set rst = cnSrc.Execute _
("SELECT MsgID,DelayTime,Receiver,Title,MsgInfo,Type,SendMode FROM Msg_Queue")
Set objLogFile = objFSO.OpenTextFile(LogFile, ForAppending, True)
Do until rst.eof
'Wscript.StdOut.WriteLine(rst("now() & VBTAB & MsgID : " & rst("MsgID") & VBTAB & rst("Title") & VBTAB & rst("MsgInfo"))
RTXParams.Remove "SENDMODE"
'RTXParams.Add "MSGID", rst("MsgID")
'RTXParams.Add "ASSTYPE", "0"
RTXParams.Add "DELAYTIME", rst("DelayTime")*1000
RTXParams.Add "USERNAME", rst("Receiver")
RTXParams.Add "TITLE", rst("Title")
RTXParams.Add "MSGINFO", rst("MsgInfo")
RTXParams.Add "TYPE", rst("Type") '0 - 普通消息;1 - 紧急消息
iSendMode = 0
if rst("SendMode") = 1 then
iSendMode = iSendMode + &H1 '发送给所有用户
end if
if iSendMode > 0 then
iSendMode = iSendMode + &H10 '需要查询状态
RTXParams.Add "SENDMODE", iSendMode
end if
On error resume next
RTXResult = ""
RTXResult = RTXobj.Call2(&H2100, RTXParams)
if( err.number < 0) then
objLogFile.Write now() & VBTAB & err.Description
objLogFile.Write VBTAB & "MsgID : " & rst("MsgID") & VBTAB & rst("Title")
objLogFile.Write VBTAB & rst("MsgInfo")
objLogFile.Write VbCrLf
else
objLogFile.Write now() & VBTAB & "发送成功"
objLogFile.Write VBTAB & "MsgID : " & rst("MsgID") & VBTAB & rst("Title")
objLogFile.Write VBTAB & rst("MsgInfo")
objLogFile.Write VbCrLf
cnSrc.Execute "DELETE FROM Msg_Queue WHERE MsgID=" & rst("MsgID")
'rst.Delete
Wscript.Sleep 10*1000
end if
rst.MoveNext
Loop
set rst = Nothing
cnSrc.close
objLogFile.Close
Wscript.Sleep CycleTime*1000*60
WEnd
脚本需要在RTX服务器上运行,且SDK Server服务必须启动。(推荐做法)
如果在其它计算机上运行脚本,需要安装RTX的SDK,配置SDK安装目录下RTXServerAPI.ini中RTX服务器的IP地址,还要修改RTX SDK Server的IP限制(修改RTX服务器安装目录下 SDKProperty.XML)。
OK,改完了配置就把服务重启一下,然后往消息队列表随便写点什么内容,测试一下脚本运行是否正常,再歇一会儿~~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
AFTER INSERT
AS
/***********************************************
Author: 碟子 http://cancelpj.cnblogs.com/
Date: 2008-02-17
Description: 当Excel服务器产生新的工作流待办事宜时,
将信息发送到RTX消息队列。
***********************************************/
BEGIN
DECLARE @Receiver VarChar(20)
DECLARE @MsgInfo VarChar(500)
--获取接收人的RTX号,以及待发送的消息内容。
SELECT @Receiver = u.MobilePhone,
/**
p.pName+'_'+t.tName as [任务],
case wi.state1
when 2
then isnull(wi.untreadName,wi.creByName)
else wi.creByName
end as [交办人],
convert(smalldatetime,case wi.state1
when 2
then isnull(wi.UntreadTime,wi.creDate)
else wi.creDate
end,120) as [交办时间],
**/
@MsgInfo = case wi.state1
when 1
then N'暂存:'
when 2
then N'被退回:'
else ''
end + '
任务:'+
p.pName+'_'+t.tName + '
交办人:'+
case wi.state1
when 2
then isnull(wi.untreadName,wi.creByName)
else wi.creByName
end + '
交办时间:'+
convert(nvarchar,case wi.state1
when 2
then isnull(wi.UntreadTime,wi.creDate)
else wi.creDate
end,120)
-- + wi.wiDesc
FROM CFWorkitems wi, CFTasks t, CFwiTodo a, CFProcesses p, Users u, Inserted i
WHERE u.UserID = a.userId and wi.wiId = a.wiId --and wi.tId=t.tId and wi.pId=p.pId
and t.tType<>3 and wi.state =0 and a.userId = i.userId
ORDER BY (case wi.state1 when 2 then isnull(wi.Untreadtime,wi.creDate) else wi.creDate end) desc
--由于ES本身在存储表单数据的过程中使用了事务,再在触发器中操作远程数据库就会引起【嵌套事务】。
--以上是个人猜测,未经证实;以下是针对“无法在此会话中启动更多的事务”的解决方法。
--用于 SQL Server 的 Microsoft OLE DB 提供程序不支持嵌套事务。
--因此,对于隐性或显式事务的内部数据修改操作和分布式分区视图上的数据修改操作,
--应将 XACT_ABORT 设置为 ON。
SET XACT_ABORT ON
--用触发器修改远程数据的两种方式。
--方式一:较安全,配置较复杂。
-- 需要在源数据库服务器建立一个指向目标服务器的链接服务器,
-- 登陆方式保存在链接服务器中,不会在触发器中显示,比较安全。
/**
INSERT INTO [RTX数据库地址].RTX.dbo.Msg_Queue(Receiver,Title,MsgInfo)
VALUES(@Receiver,'Excel服务器消息提醒',@MsgInfo)
**/
--方式二:不安全,无需另外配置。
INSERT INTO OPENDATASOURCE('SQLOLEDB','Data Source=RTX数据库地址;User ID=rtx;Password=rtx'
).RTX.dbo.Msg_Queue(Receiver,Title,MsgInfo)
VALUES(@Receiver,'消息提醒','Excel服务器消息提醒
'+@MsgInfo)
END
GO
--设置该触发器为最后执行
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服务器这边完成,其它应用服务器只提供各自的消息队列表,我觉得蛮有道理的,不过那样就不能用脚本来写程序了,所有应用服务器的后台数据库密码要明文写在脚本里面太不安全了,过段时间用其它语言写一个像模像样的程序吧,最好还是运行后在桌面右下角有图标的~~
抛砖引玉,如果看官从中获得了一点点启发,那我就很欣慰了,如果你把我后面想做的事都做了,就把代码发我一份吧~~ (懒人嘛
)
相关文章推荐
- SignalR SelfHost实时消息,集成到web中,实现服务器消息推送
- 《企业集成模式.设计、构建及部署消息传递解决方案》学习笔记
- 《企业集成模式.设计、构建及部署消息传递解决方案》学习笔记
- 《企业集成模式.设计、构建及部署消息传递解决方案》学习笔记
- 《企业集成模式.设计、构建及部署消息传递解决方案》学习笔记
- MSMQ 跨服务器读写队列的“消息队列系统的访问被拒绝”的解决方案
- winSCP:无权访问。 错误码:3 服务器返回的错误消息:Permission denied(真正解决方案)
- 微信公众平台 接口设置出现“你的服务器没有正确响应Token验证,请阅读消息接口使用指南”解决方案 Python
- 关于androidpn消息当服务器重启后,客户端在线的session全部掉线解决方案
- SpringBoot ——kafka消费多个不同服务器地址消息解决方案
- MSMQ 跨服务器读写队列的“消息队列系统的访问被拒绝”的解决方案
- 数据连接到 Web 服务 InfoPath 2010 窗体中的 SharePoint 服务器上运行时的错误消息:"401-未经授权"解决方案
- Jenkins集成及在服务器上发布异常 解决方案汇总
- 腾讯通改了服务器IP地址后,只能发送即时消息,不能发送文件
- SignalR SelfHost实时消息,集成到web中,实现服务器消息推送
- PHP web服务器终极解决方案:CentOS v6.x Minimal 32bit + LNAMP 一键安装包【Linux+Nginx+Apache+MySQL+PHP+phpMyAdmin】
- 使用 WebSphere Studio Application Developer 集成版,版本 4.1 开发 Java 消息服务应用程序
- 分析器错误消息: 无法识别的属性“targetFramework”。请注意属性名称区分大小写。 的解决方案
- James服务器与办公自动化系统的集成
- 链接服务器"(null)"的 OLE DB 访问接口 "Microsoft.Jet.OLEDB.4.0" 返回了消息 "未指定的错误"