-- example to show basic queue usage. Sender sends a postcard
-- to a receiver. Receiver waits at mail box 'till mail
-- arrives, then reads postcard

use master

drop database OneWay
go

-- make a database to hold example
Create database OneWay
go

use OneWay
go

-- we will send a post card from
-- one service to another, here
-- is a message type for a postcard
Create Message Type PostCard
validation = none
go


-- We need a contract that
-- specifies that a postcard
-- can be sent.
-- Note that only an INITIATOR
-- can send a post card
create Contract Mail
(
PostCard SENT BY INITIATOR
)
go


-- create some queues
-- even though we are sending a
-- postcard in a single direction
-- each particpant requires a queue

-- a post office is a place to send postcards
create QUEUE PostOffice
-- you pick up you mail from a mail box
create QUEUE MailBox


-- now we need some services.
-- we need two services because
-- messages can only be sent 
-- between services
-- note that the send will receive
-- error in the post office queue
Create service Sender ON QUEUE PostOffice


-- Receiver is intended to receive post card
-- so it requires a contract that says it
-- can receive post cards. The receiver
-- will receive post cards in the MailBox
-- Queue. The contract only allows post cards,
-- no bills or junk mail are allowed
Create service Receiver ON QUEUE MailBox (Mail)

-- a dialog is required to send something
-- we will  need a place to hold the
-- identifier of our dialog
declare @dialog uniqueidentifier

-- now must begin a dialog between
-- the sender and receiver
BEGIN DIALOG @dialog FROM SERVICE Sender TO SERVICE 'Receiver'
ON CONTRACT Mail 


-- now we can send a post card
-- lets make up a messsage to send
declare @message nvarchar(max)
set @message = N'Wish you were here.'

-- stick the message onto the postcard and send it
-- not that Service Broker know were to send the 
-- message because from and two were defined 
-- in the dialog, identified by the @dialog
-- variable
;send ON CONVERSATION @dialog MESSAGE TYPE PostCard
(convert(varbinary(max), @message))



-- >>>>>>>>>>>>>>>>>>>>>> Test 1, simple sending of message via queue <<<<<<<<<<<<<<<<<<<<<


-- let's see if the message made it
-- we will need a variable to hold the result
declare @postcardMessage varbinary(max)
-- wait around by the mail box for
-- something to arrive
WAITFOR (
receive TOP(1) @postcardMessage = message_body 
from MailBox )

-- let's read the postcard we received
print convert(nvarchar(max), @postcardMessage)



-- >>>>>>>>>>>>>> Test 2, sending a message but letting it timeout <<<<<<<<<<<<<<<<<<<<<<<<<
-- this illustrates that errors appear in the senders queue,
-- not as a return value from a function



-- try sending the message again, but 
-- include a timeout and don't look
-- in the mail box for the message
declare @dialog uniqueidentifier

BEGIN DIALOG @dialog FROM SERVICE Sender TO SERVICE 'Receiver'
ON CONTRACT Mail with LIFETIME = 2


-- now we can send a post card
-- lets make up a messsage to send
declare @message nvarchar(max)
set @message = N'Wish you were here.'

-- stick the message onto the postcard and send it
;send ON CONVERSATION @dialog MESSAGE TYPE PostCard
(convert(varbinary(max), @message))



-- instead of hanging around the mail box,
-- let's hang around the post office and
-- see what happens
declare @messageBody varbinary(max)
declare @messageType nvarchar(256)
WAITFOR (
receive TOP(1) @messageType = message_type_name, @messageBody = message_body 
from PostOffice )


-- we received an error, print it out to
-- see what it is
print @messageType
print convert(nvarchar(max), @messageBody)

-- this is why even for a one way communication
-- two services are required. The sender must have
-- a queue to recieve any error messages. In general
-- Service Broker operations do not produce error results
-- as the are called. That would requier an application
-- to wait for Service Broker to figure out if there
-- was an error. Instead errors are deferred and sent to
-- the service's queue



