
use master
go
drop database SimpleQueue
go

Create database SimpleQueue
go
use SimpleQueue
go

-- messages services will use
Create message type [http://game/PingMsg] validation = empty
Create message type [http://game/PongMsg] validation = empty
Create message type [http://game/Done] validation = empty

-- simple queues, messages will be
-- read from app code, Service Broker
-- will not invoke any service procdures
Create queue pong
Create queue ping


Create Contract PingPongContract
([http://game/PingMsg] sent by INITIATOR,
[http://game/PongMsg] sent by TARGET,
[http://game/Done] sent by TARGET
)
go


-- PpngSvs can only be initiator or a target for the
-- PingPongContract
Create Service PongSvs on queue Pong  (PingPongContract)

-- PingSvs can only be initiator, never target because
-- it has no target contracts
Create Service PingSvs on queue Ping

go


create Proc StartPingPong
as
go

alter Proc StartPingPong
(@lifetime int = 5)
as
declare @d1 uniqueidentifier
declare @test int
BEGIN dialog conversation @d1 from service PingSvs to service 'PongSvs'
	on contract PingPongContract with lifetime = @lifetime
;send on conversation @d1 message type [http://game/PingMsg]
print 'send' + convert(varchar(max), @d1)
go

create PROCEDURE CheckQueues
as
go
alter PROCEDURE CheckQueues
as
declare @d2 uniqueidentifier
declare @d3 uniqueidentifier
declare @mt nvarchar(256)
declare @mb varbinary(max)


waitfor (
receive TOP(1) @d2 = conversation_handle, @mt = message_type_name, @mb = message_body From  ping), Timeout 100
if(@@rowcount > 0)
BEGIN
	print 'received message type ' + convert(varchar(max), @mt)
	if @mt = 'http://game/Done'
	BEGIN
		END CONVERSATION @d2
		print 'Pong is done'
	END
	if @mt = 'http://game/PongMsg'
	BEGIN
		print 'Received from ping queue'
		print @mt
		print convert(nvarchar(max), @mb) 
	END
	if @mt = 'http://schemas.microsoft.com/SQL/ServiceBroker/Error'
	BEGIN
		print 'Received error from ping queue'
		print convert(nvarchar(max), @mb) 
	END
END
ELSE
	print 'ping empty'

waitfor (
receive TOP(1) @d2 = conversation_handle, @mt = message_type_name, @mb = message_body From  pong), Timeout 100

if(@@rowcount > 0)
BEGIN	print 'Received from pong queue'
		if @mt = 'http://game/PingMsg'
		BEGIN
			send on conversation @d2 message type [http://game/PongMsg]
			WAITFOR DELAY '00:00:02'
			;send on conversation @d2 message type [http://game/Done]
		END
	print @mt
	print convert(nvarchar(max), @mb) 
END
ELSE
	print 'pong empty'
go


create PROCEDURE EmptyQueues
as
go

alter PROCEDURE EmptyQueues
as
declare @dialog uniqueidentifier
declare @mt nvarchar(256)
declare @mb varbinary(max)
declare @more int
declare @more1 int
declare @more2 int
declare @retries int
declare @more1Error bit
declare @more2Error bit
set @retries = 4
set @more = 1
set @more1Error = 0
set @more2Error = 0
while @more > 0  or @retries > 0
BEGIN
	set @more1 = 0
	set @more2 = 0
	set @retries = @retries - 1
	waitfor (
	receive TOP(1) @dialog = conversation_handle, @mt = message_type_name, @mb = message_body From  ping), Timeout 10
	if(@@rowcount > 0)
	BEGIN
		print '----------------------'
		print 'received message from ping queue'
		if @mt = 'http://game/PingMsg'
		BEGIN
			set @more1 = 1
			print 'Ping'
		END
		if @mt = 'http://game/PongMsg'
		BEGIN
			set @more1 = 1
			print 'Pong'
			-- extend the time to allow for
			-- another pong
			BEGIN CONVERSATION TIMER (@dialog) TIMEOUT = 6000
		END
		if @mt = 'http://game/PongDone'
		BEGIN
			END CONVERSATION @dialog
			set @more1 = 1
			print 'Done'
		END
		if @more1 = 0		
		BEGIN
			set @more1Error = 1
			set @more1 = 1
			print convert(nvarchar(max), @mt) + ' message'
			print convert(nvarchar(max), @mb)
		END
	END


	waitfor (
	receive TOP(1) @dialog = conversation_handle, @mt = message_type_name, @mb = message_body From  pong), Timeout 10
	if(@@rowcount > 0)
	BEGIN
		print '----------------------'
		print 'received message from pong queue'
		if @mt = 'http://game/PingMsg'
		BEGIN
			print 'Ping'
			set @more2 = 1
			if @more2Error = 0
			send on conversation @dialog message type [http://game/PongMsg]
			declare @pass int
			set @pass = 6
			while @pass > 0 and @more2Error = 0
			BEGIN
				set @pass = @pass - 1
				;send on conversation @dialog message type [http://game/PongMsg]
				--WAITFOR DELAY '00:00:02'
			END
			;send on conversation @dialog message type [http://game/Done]
		END
		if @mt = 'http://game/PongMsg'
		BEGIN
			set @more2 = 1
			print 'Pong'
		END
		if @mt = 'http://game/PongDone'
		BEGIN
			set @more2 = 1
			print 'Done'
		END
		if @more2 = 0
		BEGIN
			set @more2Error = 1
			set @more2 = 1
			print convert(nvarchar(max), @mt) + ' message'
			print convert(nvarchar(max), @mb)
			
		END
	END
	set @more = @more1 + @more2
	-- if more to do wait a little bit for stuff to appear
	if @more = 1
	BEGIN
		set @retries = 4
		WAITFOR DELAY '00:00:02'
	END
END
print 'Queue Wait Finished'

go

Create PROC DispatchMessage
as
go
ALTER PROC DispatchMessage
AS


go







exec StartPingPong 30
exec EmptyQueues
exec CheckQueues


select * from sys.service_contract_message_usages
select * from sys.service_message_types
select * from sys.service_queues
select * from sys.service_contracts
select * from sys.service_contract_usages
