1.定义数据类型、协议和服务(发送服务和接收服务)
USE master; GO ALTER DATABASE 目标数据库 SET ENABLE_BROKER; GO -- 如果上面的操作执行后,长时间无反应,有死机的嫌疑,尝试下面的语句。 ALTER DATABASE 目标数据库 SET NEW_BROKER WITH ROLLBACK IMMEDIATE; GO ALTER DATABASE 目标数据库 SET ENABLE_BROKER; GO
-- 创建 SayHelloMessage 消息类型. -- 该消息类型,不做数据验证的处理. CREATE MESSAGE TYPE SayHelloMessage VALIDATION = None; GO -- 创建 约定 SayHelloContract -- 定义了,发送/接收方. -- 都是用这个消息类型. CREATE CONTRACT SayHelloContract ( SayHelloMessage SENT BY ANY ); GO -- 创建发送/接收队列 CREATE QUEUE SayHelloSendQueue; CREATE QUEUE SayHelloReceiveQueue; GO -- 创建发起方服务 SayHelloSendService -- 该服务使用 SayHelloSendQueue 队列 -- 由于未指定约定名称,因而其他服务不可将此服务用作目标服务。 CREATE SERVICE SayHelloSendService ON QUEUE SayHelloSendQueue; GO -- 创建目标服务 SayHelloReceiveService -- 该服务使用 SayHelloReceiveQueue 队列 -- 使用 SayHelloContract 约定 CREATE SERVICE SayHelloReceiveService ON QUEUE SayHelloReceiveQueue ([SayHelloContract]); GO
2. 发送消息
-- 定义发送的句柄. DECLARE @InitDlgHandle UNIQUEIDENTIFIER; -- 定义变量. DECLARE @MyMessage NVARCHAR(100); -- 设置发送消息的内容. SET @MyMessage = N'Hello World!' -- 开始事务处理. BEGIN TRANSACTION; -- 定义消息发送处理. BEGIN DIALOG @InitDlgHandle FROM SERVICE -- 定义发送服务. SayHelloSendService TO SERVICE -- 定义接收服务. N'SayHelloReceiveService' ON CONTRACT -- 定义使用的约定 SayHelloContract WITH -- 不加密. ENCRYPTION = OFF; -- 发送消息. SEND ON CONVERSATION @InitDlgHandle MESSAGE TYPE [SayHelloMessage] ( @MyMessage ); -- 输出接收到的消息. PRINT '我发送了:' + @MyMessage; -- 提交事务. COMMIT TRANSACTION;
3.接收消息
-- 接收句柄. DECLARE @RecvReqDlgHandle UNIQUEIDENTIFIER; -- 接收到的数据. DECLARE @RecvReqMsg NVARCHAR(100); -- 接收到的数据类型名称. DECLARE @RecvReqMsgName sysname; -- 开始事务处理. BEGIN TRANSACTION; -- 尝试从 SayHelloReceiveQueue 队列 接收消息. WAITFOR ( RECEIVE TOP(1) @RecvReqDlgHandle = conversation_handle, @RecvReqMsg = message_body, @RecvReqMsgName = message_type_name FROM SayHelloReceiveQueue ), TIMEOUT 1000; -- 如果接收到的消息类型名为 SayHelloMessage -- 那么进行处理. IF @RecvReqMsgName = N'SayHelloMessage' BEGIN -- 定义准备用于返回的消息. DECLARE @ReplyMsg NVARCHAR(100); -- 简单设置. SELECT @ReplyMsg = '~' + @RecvReqMsg + '~'; -- 调试输出. declare @t nvarchar(max) PRINT '我接收到:' + @RecvReqMsg + '; 我将反馈:' + @ReplyMsg; -- 发送反馈消息. --SEND ON CONVERSATION @RecvReqDlgHandle -- MESSAGE TYPE -- [SayHelloMessage] -- (@ReplyMsg); --END CONVERSATION @RecvReqDlgHandle; END; -- 提交事务. COMMIT TRANSACTION;
4.存储过程与队列绑定,当有消息时自动处理。
ALTER QUEUE SayHelloReceiveQueue WITH ACTIVATION ( STATUS = ON, PROCEDURE_NAME = SayHelloQueueProc, MAX_QUEUE_READERS = 10, EXECUTE AS SELF ); GO
ALTER PROCEDURE SayHelloQueueProc AS BEGIN -- 接收句柄. DECLARE @RecvReqDlgHandle UNIQUEIDENTIFIER; -- 接收到的数据. DECLARE @RecvReqMsg NVARCHAR(100); -- 接收到的数据类型名称. DECLARE @RecvReqMsgName sysname; -- 循环处理. WHILE (1=1) BEGIN -- 开始事务处理. BEGIN TRANSACTION; -- 尝试从 SayHelloReceiveQueue 队列 接收消息. WAITFOR ( RECEIVE TOP(1) @RecvReqDlgHandle = conversation_handle, @RecvReqMsg = message_body, @RecvReqMsgName = message_type_name FROM SayHelloReceiveQueue ), TIMEOUT 5000; -- 判断有没有获取到消息. IF (@@ROWCOUNT = 0) BEGIN -- 如果没有接收到消息 -- 回滚事务. ROLLBACK TRANSACTION; -- 跳出循环. BREAK; END -- 如果接收到的消息类型名为 SayHelloMessage -- 那么进行处理. IF @RecvReqMsgName = N'SayHelloMessage' BEGIN -- 定义准备用于返回的消息. DECLARE @ReplyMsg NVARCHAR(100); -- 简单设置. SELECT @ReplyMsg = '~' + @RecvReqMsg + '~'; -- 调试输出. PRINT '我接收到:' + @RecvReqMsg + '; 我将反馈:' + @ReplyMsg; insert into t_Msg(Msg) values(@RecvReqMsg); -- 发送反馈消息. SEND ON CONVERSATION @RecvReqDlgHandle MESSAGE TYPE [SayHelloMessage] (@ReplyMsg); END CONVERSATION @RecvReqDlgHandle; END; -- 提交事务. COMMIT TRANSACTION; END END GO