In the previous article, we will continue to introduce the pub/sub mode of shuttle ESB.
In the previous article, we have already used a language to describe a scenario implemented using ESB. The following shows me the specific code implementation.
First, we need to understand the functions of each DLL in shuttle ESB:
Shuttle. Core. Data: a lightweight framework that uses factory and interfaces of ADO. net
Shuttle. Core. Domain: Provides event scheduling support
Shuttle. Core. HOST: a general-purpose host that can run in a console application or a Windows Service
Shuttle. Core. Infrastructure: basic services of shuttle ESB
Shuttle. ESB. Core: Core Implementation of shuttle
Shuttle. ESB. modules: extended services of shuttle
Shuttle. ESB. MSMQ: Implementation of shuttle based on Microsoft Message Queue
Shuttle. ESB. sqlserver: Table Queue Based on sqlserver Database
1. Message entity
Create a project publishsubscribe. message, and add two message event entities: ordercompletedevent and workdoneevent. (I have already introduced the two message event entities.) use two message event entities, to prevent endless loops.
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. Message publishing end
The main function of the message publishing end is to start an ESB instance to broadcast messages, listen to message queues, and prepare to receive messages.
A. Add reference
Create the console application publishsubscribe. Publish, and then use nuget to add the following reference:
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
The configuration file mainly configures the database connection string and the shuttle ESB listening queue information.
<?xml version="1.0"?><configuration><configSections><section name="serviceBus" type="Shuttle.ESB.Core.ServiceBusSection, Shuttle.ESB.Core"/><section name="sqlServer" type="Shuttle.ESB.SqlServer.SqlServerSection, Shuttle.ESB.SqlServer"/></configSections><appSettings><add key="SubscriptionManagerSecured" value="false"/></appSettings> <connectionStrings> <clear/> <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 workQueueUri="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 program, take the following steps to start the ESB Service Bus instance: connect to the database, obtain various services of the ESB, set the listening queue of the specified message type for the ESB instance, start the ESB instance, and send messages.
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 the database new connectionstringservice (). approve (); // obtain various ESB services var subscriptionmanager = subscriptionmanager. default (); // set the ESB instance to listen to the 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) {// enter a value in the console string S = console. readline (); // send the message var message = new ordercompletedevent {coment = s}; bus. publish (Message); console. writeline ("published coment = {0}", message. coment );}}}}
D. General processing program
Add class: workdoneeventhandler.
This type of integration must inherit the imessagehandler interface. It is mainly used to receive and process 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 Receiver
The configurations of the message receiving end are similar to those of the message sending end. Because both of them can send or receive messages. However, since the message receiver is not necessarily a console program, what if it is a class library? After the command is executed, the message is released. How does one receive the message (because after the ESB instance is started, the program runs to listen to the new message )? Shuttle ESB uses a common host.
A. Add reference
Create the publishsubscribe. subscriber1 class library project and add the project reference:
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 similar to the configuration of the message sending end. It mainly configures the database connection string and the shuttle ESB listening queue information.
<?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
Here, the servicebus1host class must inherit the ihost interface of shuttle ESB and implement its start method.
Here, the functions to be implemented are similar to those of the message sender:
Connect to the database, obtain various services of the ESB, set the listening queue of the specified message type for the ESB instance, start the ESB instance, and process the message.
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 IServiceBus 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 program
Add the subscriber1handler class:
This type of integration must inherit the imessagehandler interface. It is mainly used to receive pub messages from the message sender. After processing, the messages are re-sent.
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); // send the message context. publish (New workdoneevent {comment = comment});} public bool isreusable {get {return true ;}}}}
E. Modify the startup mode.
Click Properties of the project, select "Start Operation" in the debugging bar, and select "Start external application ". Select the program shuttle.core.host.exe under the project directory debugas the Startup Program. For example, the selected directory is as follows: "D: \ publishsubscribe. subscriber1 \ bin \ debug \ shuttle.core.host.exe"
4. Message Receiver B
It completely copies the Message Receiver A and encodes the Message Receiver B.
Then, modify the startup method of the solution to multi-project startup: Set the message sender and multiple message receivers as startup projects.
5. Result demonstration
Figure 1 shows the server window, and figure 2 shows two client windows. After the program is started, the following three consoles will appear. Enter "Hello World!" on the server !" Then, two clients (of course, more clients, but too many clients will affect the receiving efficiency) receive messages immediately. After receiving the message, it returns a message to the server, and then the server receives messages from both clients. Specific results.
(Figure 1)
(Figure 2)
PS: The two clients here are two terminal display machines. Each terminal display machine can have multiple terminal Display Interfaces. Therefore, client 1 and client 2 are usually in different operating environments.
Source code download
Shuttle ESB (5) -- Implementation of instances in publish/subscribe mode (2)