Showing posts with label dialog. Show all posts
Showing posts with label dialog. Show all posts

Wednesday, March 21, 2012

Problems communicating across services.

Hello,

I am writting two applications that talk to each other. I create a service and then a dialog that points to Client2Service which means it is talking to it self. When I do that it works because I get pack the string "client1" which I am forcing it to send if it is calling ServiceProc in client1. I cahnge the Client2Service to Client1Service and it does not work any more. I do not understand why but am guessing it has something to do with the way I have the database setup. The installation script is bellow. Please share your thoughts because I am running out of ideas.

USE master;

GO

CREATE DATABASE ssb_FloorSystem;

GO

USE ssb_FloorSystem;

GO

CREATE MESSAGE TYPE Request VALIDATION = None;

CREATE MESSAGE TYPE Response VALIDATION = None;

GO

CREATE CONTRACT MessageTalk(

Request SENT BY INITIATOR,

Response SENT BY TARGET

);

GO

-- Install assemblies

BEGIN TRY

CREATE ASSEMBLY BrokerLibraryAssembly

FROM 'c:\ServiceBroker\Client1\Client1\bin\Debug\ServiceBrokerInterface.dll'

END TRY

BEGIN CATCH

-- Catch and handle exception

END CATCH;

GO

BEGIN TRY

CREATE ASSEMBLY SqlClient1BrokerServiceAssembly

FROM 'c:\ServiceBroker\Client1\Client1\bin\Debug\SqlClient1BrokerService.dll'

END TRY

BEGIN CATCH

-- Catch and handle exception

END CATCH;

GO

BEGIN TRY

CREATE ASSEMBLY SqlClient2BrokerServiceAssembly

FROM 'c:\ServiceBroker\Client2\Client2\bin\Debug\SqlClient2BrokerService.dll'

END TRY

BEGIN CATCH

-- Catch and handle exception

END CATCH;

GO

CREATE PROCEDURE Client1ServiceProc

AS

EXTERNAL NAME SqlClient1BrokerServiceAssembly.[SqlBrokerServiceNS.SqlBrokerService].ServiceProc

GO

CREATE PROCEDURE Client2ServiceProc

AS

EXTERNAL NAME SqlClient2BrokerServiceAssembly.[SqlBrokerServiceNS.SqlBrokerService].ServiceProc

GO

CREATE QUEUE Client1ServiceQueue

WITH

STATUS = ON,

RETENTION = ON,

ACTIVATION (

STATUS = ON,

PROCEDURE_NAME = Client2ServiceProc,

MAX_QUEUE_READERS = 4,

EXECUTE AS SELf

)

ON [default];

GO

CREATE QUEUE Client2ServiceQueue

WITH

STATUS = ON,

RETENTION = ON,

ACTIVATION (

STATUS = ON,

PROCEDURE_NAME = Client1ServiceProc,

MAX_QUEUE_READERS = 4,

EXECUTE AS SELf

)

ON [default];

GO

CREATE QUEUE [dbo].[ClientQueue] WITH STATUS = ON;

GO

CREATE SERVICE Client1Service ON QUEUE Client1ServiceQueue (

MessageTalk,

[http://schemas.microsoft.com/SQL/ServiceBroker/ServiceEcho]

);

GO

CREATE SERVICE Client2Service ON QUEUE Client2ServiceQueue (

MessageTalk,

[http://schemas.microsoft.com/SQL/ServiceBroker/ServiceEcho]

);

GO

CREATE SERVICE HelloWorldClient ON QUEUE ClientQueue (

MessageTalk,

[http://schemas.microsoft.com/SQL/ServiceBroker/ServiceEcho]

);

GO

EXEC sp_configure 'clr enabled', 1

GO

RECONFIGURE WITH OVERRIDE

GO

USE master;

GO

Thanks,

Scott Allison...

How are you beginning the dialog and sending the message? Did you try to diagnose the problem by looking at (i.e. simply doing a select * from...):

1. the initiator queue

2. the target quueue

3. sys.transmission_queue

|||

Hello Rushi,

I tried

select * from sys.dm_broker_activated_tasks

select * from sys.transmission_queue

and they both returned nothing. The code to send it bellow.

try

{

// Create a connection

conn = new SqlConnection(

"Initial Catalog=ssb_FloorSystem; Data Source=localhost;Integrated Security=SSPI;");

// Open the connection

conn.Open();

// Begin a transaction

tran = conn.BeginTransaction();

// Create a service object

client = new Service("HelloWorldClient", conn, tran);

// Set the FetchSize to 1 since we will receive one message at a time

// i.e. use RECEIVE TOP(1)

client.FetchSize = 1;

// Begin a dialog with the HelloWorld service

dialog = client.BeginDialog(

"Client1Service",

null,

"MessageTalk",

TimeSpan.FromMinutes(1),

false,

conn,

tran);

// Create an empty request message

MemoryStream body = new MemoryStream(Encoding.ASCII.GetBytes(Msg));

Message request = new Message("Request", body);

// Send the message to the service

dialog.Send(request, conn, tran);

tran.Commit(); // Message isn't sent until transaction has been committed

}

catch

{

tran.Rollback();

}

While the Code to recieve is bellow.

public string GetMessage(SqlConnection conn, Conversation dialog, Service client, SqlTransaction tran)

{

TextReader reader = null;

try

{

// Begin a transaction

tran = conn.BeginTransaction();

Console.WriteLine("\nTransaction 1 begun");

client.WaitforTimeout = TimeSpan.FromSeconds(5);

if (client.GetConversation(dialog, conn, tran) == null)

{

Console.WriteLine("No message received - Ending dialog with Error");

dialog.EndWithError(1, "no response within 5 seconds.", conn, tran);

tran.Commit();

Console.WriteLine("Transaction 2 committed");

conn.Close();

Console.WriteLine("\nConnection closed - exiting");

return "";

}

// Fetch the message from the conversation

Message response = dialog.Receive();

// Output the message to the Console

//Console.WriteLine("Message received of type '" + response.Type + "'");

if (response.Body != null)

{

reader = new StreamReader(response.Body);

}

// End the conversation

dialog.End(conn, tran);

Console.WriteLine("Ended Dialog");

//tran.Commit(); // Remember to commit again

Console.WriteLine("Transaction 2 committed");

// Close the database connection

conn.Close();

Console.WriteLine("\nConnection closed - exiting");

if (response.Body != null)

return reader.ReadToEnd();

return "";

}

catch (ServiceException e)

{

Console.WriteLine("An exception occurred - {0}\n", e.ToString());

if (tran != null)

{

tran.Rollback();

Console.WriteLine("\nTransaction rolled back");

}

if (conn != null)

{

conn.Close();

Console.WriteLine("\nConnection closed - exiting");

}

return "";

}

finally

{

if (reader != null)

reader.Close();

Console.WriteLine();

Console.WriteLine("Press Enter to Exit");

Console.ReadLine();

}

}

Thanks,

Scott Allison...