We continue with an article to introduce the pub/sub pattern of the shuttle ESB.
In the previous article, we have already described a scenario implemented with an ESB using the language, which gives me a concrete code implementation.
First, we need to look at the capabilities of the shuttle ESB individual DLLs:
Shuttle.Core.Data: Lightweight framework, using the ADO Factory and interface
Shuttle.Core.Domain: Provides event dispatch support
Shuttle.Core.Host: A universal host that can run in console applications or Windows services
Shuttle.Core.Infrastructure:Shuttle Basic services for ESB
The core realization of Shuttle.ESB.Core:Shuttle
Shuttle.ESB.Modules:Shuttle's extended service
Shuttle.ESB.MSMQ:Shuttle based on the implementation of Microsoft Message Queuing
Shuttle.ESB.SqlServer: Table queue based on SQL Server database
1. Message Entities
Create the project Publishsubscribe.message and add the Ordercompletedevent and workdoneevent two message event entities (as to why two message entities, as I have already described), use two message event entities to prevent the occurrence of a dead loop.
A, ordercompletedevent event message entity
Using System;
Namespace Publishsubscribe.messages
{public
class ordercompletedevent
{public
Guid OrderId {get; Set Public
String coment {get; set;}}
}
B, workdoneevent event message entity
Namespace Publishsubscribe.messages
{public
class workdoneevent
{public
string Comment {get; Set }
}
}
2, the message publishing end
The main function of the message publishing side is to start an ESB instance, which is primarily responsible for broadcasting messages, while listening to Message Queuing and preparing to receive messages.
A, add reference
Create a console application Publishsubscribe.publish, and then use NuGet to add the following references:
Publishsubscribe.messages
Shuttle.Core.Data
Shuttle.Core.Domain
Shuttle.Core.Host
Shuttle.Core.Infrastructure
Shuttle.ESB.Core
Shuttle.ESB.Modules
Shuttle.ESB.SqlServer
B. configuration file App. Config
Configuration file, the database connection string is primarily configured, and the listener queue information for the shuttle ESB is
<?xml version= "1.0"?> <configuration> <configSections> <section name= "Servicebus" type= " Shuttle.ESB.Core.ServiceBusSection, Shuttle.ESB.Core "/> <section name=" SQL Server "Type="
Shuttle.ESB.SqlServer.SqlServerSection, Shuttle.ESB.SqlServer "/> </configSections> <appSettings> <add key= "subscriptionmanagersecured" value= "false"/> </appSettings> <connectionStrings> <clea r/> <add name= "subscriptionconnection" connectionstring= "UID=SA; Pwd=123456;initial Catalog=shuttle;data source=172.22.51.180; Connect timeout=900 "providername=" System.Data.SqlClient "/> </connectionStrings> <sqlserver Subscriptionmanagerconnectionstringname= "Subscriptionconnection"/> <serviceBus> <inbox workQueueUr I= "Msmq://./pubsub-publish-inbox-work" deferredqueueuri= "msmq://./pubsub-publish-inbox-deferred" ErrorQueueUri = "Msmq://./shuttle-pubsub-error"/> </serviceBus> <startUp><supportedruntime version= "v4.0" sku= ".
netframework,version=v4.0 "/></startup></configuration>
C, console program
In the console program, you start the ESB service bus instance by connecting to the database, getting the various services of the ESB, setting up a listening queue for the message type specified by the ESB instance, launching the ESB instance, and sending the message.
Using System;
Using System.Collections.Generic;
Using System.Linq;
Using System.Text;
Using Shuttle.Core.Data;
Using Shuttle.ESB.SqlServer;
Using Publishsubscribe.messages;
Using Shuttle.ESB.Core;
Using Shuttle.Core.Infrastructure;
Namespace Publishsubscribe.publish {class Program {static void Main (string[] args) { Connect to database New Connectionstringservice ().
Approve ();
Get the various services of the ESB var SubscriptionManager = Subscriptionmanager.default (); Set the ESB instance listener queue type Subscriptionmanager.subscribe (new[]{typeof (Workdoneevent ).
FullName}); Start the ESB instance var bus = Servicebus.create (C=>c.subscriptionmanager (SubscriptionManager)).
Start (); Coloredconsole.writeline (Consolecolor.green, "Server bus started.
Press CTRL + C to stop. "); while (true) {//console input a value string s = COnsole.
ReadLine ();
Sent message var message = new Ordercompletedevent {coment = s
}; Bus.
Publish (message);
Console.WriteLine ("Published coment= {0}", message.coment);
}
}
}
}
D, General processing procedures
Add Class: Workdoneeventhandler.
This class of integration requires inheriting the Imessagehandler interface. The main purpose of this is to receive and process the received messages.
Using System;
Using System.Collections.Generic;
Using System.Linq;
Using System.Text;
Using Shuttle.ESB.Core;
Using Shuttle.Core.Infrastructure;
Using Publishsubscribe.messages;
Namespace Publishsubscribe
{public
class workdoneeventhandler:imessagehandler<workdoneevent>
{Public
void ProcessMessage (handlercontext<workdoneevent> context)
{
Coloredconsole.writeline (Consolecolor.blue, context.Message.Comment);
}
public bool IsReusable
{
get {return true;}
}
}
3. Message receiving end a
The configuration of the message receiving end is similar to the configuration of the message sender. Because they can all send messages, they can also receive messages. Only, because the message receiving end is not necessarily a console program, if it is a class library. After execution, it is released, how to receive the message (since the ESB instance starts, the program runs before it hears the newly received message). Shuttle the way the ESB uses a common host.
A, add reference
Create the Class library project Publishsubscribe.subscriber1 and add the project references:
Publishsubscribe.messages
Shuttle.Core.Data
Shuttle.Core.Domain
Shuttle.Core.Host
Shuttle.Core.Infrastructure
Shuttle.ESB.Core
Shuttle.ESB.Msmq
Shuttle.sqlserver
B. configuration file App. Config
The configuration file is basically similar to the configuration of the message sender, with the main configuration of the database connection string and the listening queue information for the shuttle ESB.
<?xml version= "1.0"?>
<configuration>
<configSections>
<section name= " Servicebus "Type=" Shuttle.ESB.Core.ServiceBusSection, Shuttle.ESB.Core "/>
</configSections>
<connectionStrings>
<clear/>
<add name= "Subscription" connectionstring= "UID=SA; Pwd=123456;initial Catalog=shuttle;data source=172.22.51.180; Connect timeout=900 "providername=" System.Data.SqlClient "/>
</connectionStrings>
<servicebus >
<inbox
workqueueuri= "msmq://./pubsub-subscriber1-inbox-work"
errorqueueuri= "msmq://./ Shuttle-pubsub-error "/>
</serviceBus>
<startup><supportedruntime version=" v4.0 "sku= ". netframework,version=v4.0 "/></startup></configuration>
C, class library project
The Servicebus1host class here needs to inherit the Ihost interface of the shuttle ESB and implement its Start method.
Here, the function that it needs to implement is also exactly like the message sending side:
Connect the database, get the various services of the ESB, set up an ESB instance to specify a listener queue for the message type, launch an ESB instance, process messages.
Using System;
Using System.Collections.Generic;
Using System.Linq;
Using System.Text;
Using Shuttle.ESB.Core;
Using Shuttle.Core.Data;
Using Shuttle.ESB.SqlServer;
Using Publishsubscribe.messages;
Using Shuttle.Core.Infrastructure;
Using Shuttle.Core.Host; Namespace Publishsubscribe.subscriber1 {public class Servicebus1host:ihost,idisposable {private IService
Bus bus; public void Dispose () {bus.
Dispose (); } public void Start () {new Connectionstringservice ().
Approve ();
var SubscriptionManager = Subscriptionmanager.default (); Subscriptionmanager.subscribe (new[]{typeof (Ordercompletedevent).
FullName}); Bus = servicebus.create (c = C.subscriptionmanager (SubscriptionManager)).
Start (); Coloredconsole.writeline (Consolecolor.green, "Sub 1 started.
Press CTRL + C to stop. ");}}}
D, General processing procedures
To add the Subscriber1handler class:
This class of integration requires inheriting the Imessagehandler interface. Its role is primarily to receive messages from the sending side of pub, after processing and re-hairstyles messages.
Using System;
Using System.Collections.Generic;
Using System.Linq;
Using System.Text;
Using Shuttle.ESB.Core;
Using Publishsubscribe.messages;
Using Shuttle.Core.Infrastructure;
Namespace Publishsubscribe.subscriber1
{public
class subscriber1handler:imessagehandler< ordercompletedevent>
{public
void ProcessMessage (handlercontext<ordercompletedevent> context)
{
string comment = string. Format ("Subscriber1-----lzq: {0}", context.Message.coment);
Coloredconsole.writeline (Consolecolor.blue, comment);
Sends a message to the
context. Publish (
new Workdoneevent {
Comment = Comment
}
);
}
public bool IsReusable
{
get {return true;}
}
}
E, modify the startup mode
Click on the properties of this item, select "Start Action" in the debug bar, and select "Launch external Application". Select "Shuttle.Core.Host.exe" under Debug for this project directory as the startup program. For example, I chose the following directory: "D:\PublishSubscribe\PublishSubscribe.Subscriber1\bin\Debug\Shuttle.Core.Host.exe"
4. Message Receiving end B
Completely clones the message receive side A, encoded message receiver B.
The solution is then modified to start with multi-project startup: Both the message sender and multiple message receivers are set as Startup items.
5. Results presentation
Figure 1 is the server window, and Figure 2 is the two client window. After the program is started, the following three consoles appear. Enter "Hello World" on the service side. "After that, two clients (of course can be more, but too many clients will affect the reception efficiency) immediately receive the message. When it is received, it returns a message to the server and then the server receives two client messages. The exact results are shown in the figure.
(Fig. 1)
(Fig. 2)
PS: Here are two clients are two terminal display machine, each terminal display machine can have multiple terminal display interface. Therefore, client 1 and Client 2 are often in different operating environments.
Source code Download