From 173eee4ba0831c18b12d1e7ed458dd51d8bb0987 Mon Sep 17 00:00:00 2001 From: Tim Bussmann Date: Mon, 28 Sep 2020 19:20:39 +0200 Subject: [PATCH] Create message-driven pub/sub sample (#5023) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * move native pubsub sample to subfolder * copy native sample as a starting point * switch sample to message driven pub-sub using MSMQ * create index file for sample folder * update sample description * update native sample description * Apply suggestions from code review Co-authored-by: Andreas Öhlund * rename ambiguous Start method Co-authored-by: Andreas Öhlund --- samples/pubsub/index.md | 7 +++ .../{ => message-driven}/Core_6/PubSub.sln | 0 .../Core_6/PubSub.sln.DotSettings | 0 .../Core_6/Publisher/Program.cs | 56 +++++++++++++++++++ .../Core_6/Publisher/Publisher.csproj | 0 .../Core_6/Shared/OrderReceived.cs | 0 .../Core_6/Shared/Shared.csproj | 0 .../Core_6/Subscriber/OrderReceivedHandler.cs | 0 .../Core_6/Subscriber/Program.cs | 28 ++++++++++ .../Core_6/Subscriber/Subscriber.csproj | 0 .../{ => message-driven}/Core_7/PubSub.sln | 0 .../Core_7/PubSub.sln.DotSettings | 0 .../Core_7/Publisher/Program.cs | 56 +++++++++++++++++++ .../Core_7/Publisher/Publisher.csproj | 12 ++++ .../Core_7/Shared/OrderReceived.cs | 0 .../Core_7/Shared/Shared.csproj | 9 +++ .../Core_7/Subscriber/OrderReceivedHandler.cs | 0 .../Core_7/Subscriber/Program.cs | 28 ++++++++++ .../Core_7/Subscriber/Subscriber.csproj | 12 ++++ samples/pubsub/message-driven/sample.md | 52 +++++++++++++++++ samples/pubsub/native/Core_6/PubSub.sln | 27 +++++++++ .../native/Core_6/PubSub.sln.DotSettings | 6 ++ .../{ => native}/Core_6/Publisher/Program.cs | 0 .../native/Core_6/Publisher/Publisher.csproj | 11 ++++ .../native/Core_6/Shared/OrderReceived.cs | 8 +++ .../pubsub/native/Core_6/Shared/Shared.csproj | 9 +++ .../Core_6/Subscriber/OrderReceivedHandler.cs | 15 +++++ .../{ => native}/Core_6/Subscriber/Program.cs | 0 .../Core_6/Subscriber/Subscriber.csproj | 11 ++++ samples/pubsub/native/Core_7/PubSub.sln | 27 +++++++++ .../native/Core_7/PubSub.sln.DotSettings | 6 ++ .../{ => native}/Core_7/Publisher/Program.cs | 0 .../Core_7/Publisher/Publisher.csproj | 0 .../native/Core_7/Shared/OrderReceived.cs | 8 +++ .../{ => native}/Core_7/Shared/Shared.csproj | 0 .../Core_7/Subscriber/OrderReceivedHandler.cs | 15 +++++ .../{ => native}/Core_7/Subscriber/Program.cs | 0 .../Core_7/Subscriber/Subscriber.csproj | 0 samples/pubsub/{ => native}/sample.md | 12 ++-- ...mple_faulttolerance_core_[,6.0).partial.md | 1 - ...mple_faulttolerance_core_[6.0,).partial.md | 1 - 41 files changed, 409 insertions(+), 8 deletions(-) create mode 100644 samples/pubsub/index.md rename samples/pubsub/{ => message-driven}/Core_6/PubSub.sln (100%) rename samples/pubsub/{ => message-driven}/Core_6/PubSub.sln.DotSettings (100%) create mode 100644 samples/pubsub/message-driven/Core_6/Publisher/Program.cs rename samples/pubsub/{ => message-driven}/Core_6/Publisher/Publisher.csproj (100%) rename samples/pubsub/{ => message-driven}/Core_6/Shared/OrderReceived.cs (100%) rename samples/pubsub/{ => message-driven}/Core_6/Shared/Shared.csproj (100%) rename samples/pubsub/{ => message-driven}/Core_6/Subscriber/OrderReceivedHandler.cs (100%) create mode 100644 samples/pubsub/message-driven/Core_6/Subscriber/Program.cs rename samples/pubsub/{ => message-driven}/Core_6/Subscriber/Subscriber.csproj (100%) rename samples/pubsub/{ => message-driven}/Core_7/PubSub.sln (100%) rename samples/pubsub/{ => message-driven}/Core_7/PubSub.sln.DotSettings (100%) create mode 100644 samples/pubsub/message-driven/Core_7/Publisher/Program.cs create mode 100644 samples/pubsub/message-driven/Core_7/Publisher/Publisher.csproj rename samples/pubsub/{ => message-driven}/Core_7/Shared/OrderReceived.cs (100%) create mode 100644 samples/pubsub/message-driven/Core_7/Shared/Shared.csproj rename samples/pubsub/{ => message-driven}/Core_7/Subscriber/OrderReceivedHandler.cs (100%) create mode 100644 samples/pubsub/message-driven/Core_7/Subscriber/Program.cs create mode 100644 samples/pubsub/message-driven/Core_7/Subscriber/Subscriber.csproj create mode 100644 samples/pubsub/message-driven/sample.md create mode 100644 samples/pubsub/native/Core_6/PubSub.sln create mode 100644 samples/pubsub/native/Core_6/PubSub.sln.DotSettings rename samples/pubsub/{ => native}/Core_6/Publisher/Program.cs (100%) create mode 100644 samples/pubsub/native/Core_6/Publisher/Publisher.csproj create mode 100644 samples/pubsub/native/Core_6/Shared/OrderReceived.cs create mode 100644 samples/pubsub/native/Core_6/Shared/Shared.csproj create mode 100644 samples/pubsub/native/Core_6/Subscriber/OrderReceivedHandler.cs rename samples/pubsub/{ => native}/Core_6/Subscriber/Program.cs (100%) create mode 100644 samples/pubsub/native/Core_6/Subscriber/Subscriber.csproj create mode 100644 samples/pubsub/native/Core_7/PubSub.sln create mode 100644 samples/pubsub/native/Core_7/PubSub.sln.DotSettings rename samples/pubsub/{ => native}/Core_7/Publisher/Program.cs (100%) rename samples/pubsub/{ => native}/Core_7/Publisher/Publisher.csproj (100%) create mode 100644 samples/pubsub/native/Core_7/Shared/OrderReceived.cs rename samples/pubsub/{ => native}/Core_7/Shared/Shared.csproj (100%) create mode 100644 samples/pubsub/native/Core_7/Subscriber/OrderReceivedHandler.cs rename samples/pubsub/{ => native}/Core_7/Subscriber/Program.cs (100%) rename samples/pubsub/{ => native}/Core_7/Subscriber/Subscriber.csproj (100%) rename samples/pubsub/{ => native}/sample.md (77%) delete mode 100644 samples/pubsub/sample_faulttolerance_core_[,6.0).partial.md delete mode 100644 samples/pubsub/sample_faulttolerance_core_[6.0,).partial.md diff --git a/samples/pubsub/index.md b/samples/pubsub/index.md new file mode 100644 index 00000000000..4bff0086241 --- /dev/null +++ b/samples/pubsub/index.md @@ -0,0 +1,7 @@ +--- +title: Publish/Subscribe +summary: Sample code related to publish/subscribe +reviewed: 2020-09-28 +related: + - nservicebus/messaging/publish-subscribe +--- \ No newline at end of file diff --git a/samples/pubsub/Core_6/PubSub.sln b/samples/pubsub/message-driven/Core_6/PubSub.sln similarity index 100% rename from samples/pubsub/Core_6/PubSub.sln rename to samples/pubsub/message-driven/Core_6/PubSub.sln diff --git a/samples/pubsub/Core_6/PubSub.sln.DotSettings b/samples/pubsub/message-driven/Core_6/PubSub.sln.DotSettings similarity index 100% rename from samples/pubsub/Core_6/PubSub.sln.DotSettings rename to samples/pubsub/message-driven/Core_6/PubSub.sln.DotSettings diff --git a/samples/pubsub/message-driven/Core_6/Publisher/Program.cs b/samples/pubsub/message-driven/Core_6/Publisher/Program.cs new file mode 100644 index 00000000000..31dcb9b135e --- /dev/null +++ b/samples/pubsub/message-driven/Core_6/Publisher/Program.cs @@ -0,0 +1,56 @@ +using System; +using System.Threading.Tasks; +using NServiceBus; + +static class Program +{ + static async Task Main() + { + Console.Title = "Samples.PubSub.MessageDrivenPublisher"; + var endpointConfiguration = new EndpointConfiguration("Samples.PubSub.MessageDrivenPublisher"); + endpointConfiguration.UsePersistence(); + endpointConfiguration.UseTransport(); + + endpointConfiguration.SendFailedMessagesTo("error"); + endpointConfiguration.EnableInstallers(); + + var endpointInstance = await Endpoint.Start(endpointConfiguration) + .ConfigureAwait(false); + await PublishOrderEvent(endpointInstance) + .ConfigureAwait(false); + await endpointInstance.Stop() + .ConfigureAwait(false); + } + + static async Task PublishOrderEvent(IEndpointInstance endpointInstance) + { + Console.WriteLine("Press '1' to publish the OrderReceived event"); + Console.WriteLine("Press any other key to exit"); + + #region PublishLoop + + while (true) + { + var key = Console.ReadKey(); + Console.WriteLine(); + + var orderReceivedId = Guid.NewGuid(); + if (key.Key == ConsoleKey.D1) + { + var orderReceived = new OrderReceived + { + OrderId = orderReceivedId + }; + await endpointInstance.Publish(orderReceived) + .ConfigureAwait(false); + Console.WriteLine($"Published OrderReceived Event with Id {orderReceivedId}."); + } + else + { + return; + } + } + + #endregion + } +} \ No newline at end of file diff --git a/samples/pubsub/Core_6/Publisher/Publisher.csproj b/samples/pubsub/message-driven/Core_6/Publisher/Publisher.csproj similarity index 100% rename from samples/pubsub/Core_6/Publisher/Publisher.csproj rename to samples/pubsub/message-driven/Core_6/Publisher/Publisher.csproj diff --git a/samples/pubsub/Core_6/Shared/OrderReceived.cs b/samples/pubsub/message-driven/Core_6/Shared/OrderReceived.cs similarity index 100% rename from samples/pubsub/Core_6/Shared/OrderReceived.cs rename to samples/pubsub/message-driven/Core_6/Shared/OrderReceived.cs diff --git a/samples/pubsub/Core_6/Shared/Shared.csproj b/samples/pubsub/message-driven/Core_6/Shared/Shared.csproj similarity index 100% rename from samples/pubsub/Core_6/Shared/Shared.csproj rename to samples/pubsub/message-driven/Core_6/Shared/Shared.csproj diff --git a/samples/pubsub/Core_6/Subscriber/OrderReceivedHandler.cs b/samples/pubsub/message-driven/Core_6/Subscriber/OrderReceivedHandler.cs similarity index 100% rename from samples/pubsub/Core_6/Subscriber/OrderReceivedHandler.cs rename to samples/pubsub/message-driven/Core_6/Subscriber/OrderReceivedHandler.cs diff --git a/samples/pubsub/message-driven/Core_6/Subscriber/Program.cs b/samples/pubsub/message-driven/Core_6/Subscriber/Program.cs new file mode 100644 index 00000000000..f6b84ef9b0a --- /dev/null +++ b/samples/pubsub/message-driven/Core_6/Subscriber/Program.cs @@ -0,0 +1,28 @@ +using System; +using System.Threading.Tasks; +using NServiceBus; + +static class Program +{ + static async Task Main() + { + Console.Title = "Samples.PubSub.MessageDrivenSubscriber"; + var endpointConfiguration = new EndpointConfiguration("Samples.PubSub.MessageDrivenSubscriber"); + endpointConfiguration.UsePersistence(); + + #region SubscriptionConfiguration + var transport = endpointConfiguration.UseTransport(); + transport.Routing().RegisterPublisher(typeof(OrderReceived), "Samples.PubSub.MessageDrivenPublisher"); + #endregion + + endpointConfiguration.SendFailedMessagesTo("error"); + endpointConfiguration.EnableInstallers(); + + var endpointInstance = await Endpoint.Start(endpointConfiguration) + .ConfigureAwait(false); + Console.WriteLine("Press any key to exit"); + Console.ReadKey(); + await endpointInstance.Stop() + .ConfigureAwait(false); + } +} \ No newline at end of file diff --git a/samples/pubsub/Core_6/Subscriber/Subscriber.csproj b/samples/pubsub/message-driven/Core_6/Subscriber/Subscriber.csproj similarity index 100% rename from samples/pubsub/Core_6/Subscriber/Subscriber.csproj rename to samples/pubsub/message-driven/Core_6/Subscriber/Subscriber.csproj diff --git a/samples/pubsub/Core_7/PubSub.sln b/samples/pubsub/message-driven/Core_7/PubSub.sln similarity index 100% rename from samples/pubsub/Core_7/PubSub.sln rename to samples/pubsub/message-driven/Core_7/PubSub.sln diff --git a/samples/pubsub/Core_7/PubSub.sln.DotSettings b/samples/pubsub/message-driven/Core_7/PubSub.sln.DotSettings similarity index 100% rename from samples/pubsub/Core_7/PubSub.sln.DotSettings rename to samples/pubsub/message-driven/Core_7/PubSub.sln.DotSettings diff --git a/samples/pubsub/message-driven/Core_7/Publisher/Program.cs b/samples/pubsub/message-driven/Core_7/Publisher/Program.cs new file mode 100644 index 00000000000..31dcb9b135e --- /dev/null +++ b/samples/pubsub/message-driven/Core_7/Publisher/Program.cs @@ -0,0 +1,56 @@ +using System; +using System.Threading.Tasks; +using NServiceBus; + +static class Program +{ + static async Task Main() + { + Console.Title = "Samples.PubSub.MessageDrivenPublisher"; + var endpointConfiguration = new EndpointConfiguration("Samples.PubSub.MessageDrivenPublisher"); + endpointConfiguration.UsePersistence(); + endpointConfiguration.UseTransport(); + + endpointConfiguration.SendFailedMessagesTo("error"); + endpointConfiguration.EnableInstallers(); + + var endpointInstance = await Endpoint.Start(endpointConfiguration) + .ConfigureAwait(false); + await PublishOrderEvent(endpointInstance) + .ConfigureAwait(false); + await endpointInstance.Stop() + .ConfigureAwait(false); + } + + static async Task PublishOrderEvent(IEndpointInstance endpointInstance) + { + Console.WriteLine("Press '1' to publish the OrderReceived event"); + Console.WriteLine("Press any other key to exit"); + + #region PublishLoop + + while (true) + { + var key = Console.ReadKey(); + Console.WriteLine(); + + var orderReceivedId = Guid.NewGuid(); + if (key.Key == ConsoleKey.D1) + { + var orderReceived = new OrderReceived + { + OrderId = orderReceivedId + }; + await endpointInstance.Publish(orderReceived) + .ConfigureAwait(false); + Console.WriteLine($"Published OrderReceived Event with Id {orderReceivedId}."); + } + else + { + return; + } + } + + #endregion + } +} \ No newline at end of file diff --git a/samples/pubsub/message-driven/Core_7/Publisher/Publisher.csproj b/samples/pubsub/message-driven/Core_7/Publisher/Publisher.csproj new file mode 100644 index 00000000000..fcb321c525e --- /dev/null +++ b/samples/pubsub/message-driven/Core_7/Publisher/Publisher.csproj @@ -0,0 +1,12 @@ + + + net48 + Exe + 7.3 + + + + + + + \ No newline at end of file diff --git a/samples/pubsub/Core_7/Shared/OrderReceived.cs b/samples/pubsub/message-driven/Core_7/Shared/OrderReceived.cs similarity index 100% rename from samples/pubsub/Core_7/Shared/OrderReceived.cs rename to samples/pubsub/message-driven/Core_7/Shared/OrderReceived.cs diff --git a/samples/pubsub/message-driven/Core_7/Shared/Shared.csproj b/samples/pubsub/message-driven/Core_7/Shared/Shared.csproj new file mode 100644 index 00000000000..751e57827e5 --- /dev/null +++ b/samples/pubsub/message-driven/Core_7/Shared/Shared.csproj @@ -0,0 +1,9 @@ + + + net48 + 7.3 + + + + + \ No newline at end of file diff --git a/samples/pubsub/Core_7/Subscriber/OrderReceivedHandler.cs b/samples/pubsub/message-driven/Core_7/Subscriber/OrderReceivedHandler.cs similarity index 100% rename from samples/pubsub/Core_7/Subscriber/OrderReceivedHandler.cs rename to samples/pubsub/message-driven/Core_7/Subscriber/OrderReceivedHandler.cs diff --git a/samples/pubsub/message-driven/Core_7/Subscriber/Program.cs b/samples/pubsub/message-driven/Core_7/Subscriber/Program.cs new file mode 100644 index 00000000000..f6b84ef9b0a --- /dev/null +++ b/samples/pubsub/message-driven/Core_7/Subscriber/Program.cs @@ -0,0 +1,28 @@ +using System; +using System.Threading.Tasks; +using NServiceBus; + +static class Program +{ + static async Task Main() + { + Console.Title = "Samples.PubSub.MessageDrivenSubscriber"; + var endpointConfiguration = new EndpointConfiguration("Samples.PubSub.MessageDrivenSubscriber"); + endpointConfiguration.UsePersistence(); + + #region SubscriptionConfiguration + var transport = endpointConfiguration.UseTransport(); + transport.Routing().RegisterPublisher(typeof(OrderReceived), "Samples.PubSub.MessageDrivenPublisher"); + #endregion + + endpointConfiguration.SendFailedMessagesTo("error"); + endpointConfiguration.EnableInstallers(); + + var endpointInstance = await Endpoint.Start(endpointConfiguration) + .ConfigureAwait(false); + Console.WriteLine("Press any key to exit"); + Console.ReadKey(); + await endpointInstance.Stop() + .ConfigureAwait(false); + } +} \ No newline at end of file diff --git a/samples/pubsub/message-driven/Core_7/Subscriber/Subscriber.csproj b/samples/pubsub/message-driven/Core_7/Subscriber/Subscriber.csproj new file mode 100644 index 00000000000..fcb321c525e --- /dev/null +++ b/samples/pubsub/message-driven/Core_7/Subscriber/Subscriber.csproj @@ -0,0 +1,12 @@ + + + net48 + Exe + 7.3 + + + + + + + \ No newline at end of file diff --git a/samples/pubsub/message-driven/sample.md b/samples/pubsub/message-driven/sample.md new file mode 100644 index 00000000000..7748e82d663 --- /dev/null +++ b/samples/pubsub/message-driven/sample.md @@ -0,0 +1,52 @@ +--- +title: Message-driven Publish/Subscribe +summary: Persistence based Publish/Subscribe for unicast-only transports. +reviewed: 2020-09-28 +component: Core +related: + - nservicebus/messaging/publish-subscribe +--- + +This sample shows how to publish an event from one endpoint, subscribe to the event in a separate endpoint and execute a message handler when an event is received. This sample uses the [message-driven publish-subscribe mechanism](/nservicebus/messaging/publish-subscribe#mechanics-message-driven-persistence-based) for unicast transports. + +downloadbutton + +Before running the sample, look over the solution structure, the projects and the classes. The projects `Publisher` and `Subscriber` are console applications that each host an instance of an NServiceBus messaging endpoint. + +## Defining messages + +The `Shared` project contains the definition of the messages that are sent between the processes. Open "OrderReceived.cs" to see the message that will be published by this sample. Note that this event implements an interface called `IEvent` to denote that this message is an event. To define messages without adding a dependency to NServiceBus, use [Unobtrusive Mode Messages](/nservicebus/messaging/unobtrusive-mode.md). + +## Publishing the event + +As the name implies, the `Publisher` project is a publisher of event messages. It uses the NServiceBus API to publish the `OrderReceived` event every time the `1` key is pressed. The created message is populated and [published](/nservicebus/messaging/publish-subscribe/) using the `Publish` API. + +snippet: PublishLoop + +## Subscribing to the event + +To receive messages from the publisher, the subscribers [must subscribe to the message types](/nservicebus/messaging/publish-subscribe/) they are designed to handle. A subscriber must have a handler for the type of message and a configuration that tells the endpoint where to send subscriptions for messages to: + +snippet: SubscriptionConfiguration + + * The `Subscriber` handles and subscribes to the `OrderReceived` event type. + * The handlers in each project are in files that end with the word `Handler` for example `OrderReceivedHandler.cs`. + * `Subscriber` uses the default auto-subscription feature of the bus where the bus automatically subscribes to the configured publisher. [The auto-subscribe feature can be explicitly disabled](/nservicebus/messaging/publish-subscribe/controlling-what-is-subscribed.md) as part of the endpoint configuration. + +## Run the sample + +When running the sample, two console applications will open. Bring the `Publisher` endpoint to the foreground. + +Click the `1` key repeatedly in the `Publisher` process console window and notice how the messages appear in the `Subscriber` console window. + +## Subscription mechanics + +When starting up, the `Subscriber` endpoint sends a subscription message to the `Publisher` endpoint. The `Publisher` then retrieves all subscribed endpoints from the persistence once an event is published. See the [publish-subscribe documentation](/nservicebus/messaging/publish-subscribe#mechanics-message-driven-persistence-based) for further details. + +## Fault-tolerant messaging + +Shut down `Subscriber` by closing its console window. Return to the `Publisher` process and publish a few more messages by pressing the `1` key several more times. Notice how the publishing process does not change and there are no errors even though the subscriber process is no longer running. + +In Visual Studio, right-click the project of the closed subscriber. Restart it by right-clicking the `Subscriber` project and selecting `Debug` followed by `Start new instance`. + +Note how `Subscriber` immediately receives the messages that were published while it was not running. The publisher safely places the event into the subscriber's queue without knowledge of the running status of any subscriber. Even when processes or machines restart, NServiceBus protects messages from being lost. diff --git a/samples/pubsub/native/Core_6/PubSub.sln b/samples/pubsub/native/Core_6/PubSub.sln new file mode 100644 index 00000000000..6ff60a46d4f --- /dev/null +++ b/samples/pubsub/native/Core_6/PubSub.sln @@ -0,0 +1,27 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29728.190 +MinimumVisualStudioVersion = 15.0.26730.12 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "Shared\Shared.csproj", "{5686FE6C-A5E3-40D1-A6BD-25F94DA612F8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Publisher", "Publisher\Publisher.csproj", "{7036A49B-359F-4BC7-AFBA-DE3C7AB41986}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Subscriber", "Subscriber\Subscriber.csproj", "{6A699A4E-F2FD-4B71-AF73-199B499482BD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5686FE6C-A5E3-40D1-A6BD-25F94DA612F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5686FE6C-A5E3-40D1-A6BD-25F94DA612F8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7036A49B-359F-4BC7-AFBA-DE3C7AB41986}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7036A49B-359F-4BC7-AFBA-DE3C7AB41986}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6A699A4E-F2FD-4B71-AF73-199B499482BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6A699A4E-F2FD-4B71-AF73-199B499482BD}.Debug|Any CPU.Build.0 = Debug|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/samples/pubsub/native/Core_6/PubSub.sln.DotSettings b/samples/pubsub/native/Core_6/PubSub.sln.DotSettings new file mode 100644 index 00000000000..e0cf84c1382 --- /dev/null +++ b/samples/pubsub/native/Core_6/PubSub.sln.DotSettings @@ -0,0 +1,6 @@ + + ..\..\..\..\tools\Shared.DotSettings + True + True + 1 + \ No newline at end of file diff --git a/samples/pubsub/Core_6/Publisher/Program.cs b/samples/pubsub/native/Core_6/Publisher/Program.cs similarity index 100% rename from samples/pubsub/Core_6/Publisher/Program.cs rename to samples/pubsub/native/Core_6/Publisher/Program.cs diff --git a/samples/pubsub/native/Core_6/Publisher/Publisher.csproj b/samples/pubsub/native/Core_6/Publisher/Publisher.csproj new file mode 100644 index 00000000000..02110572148 --- /dev/null +++ b/samples/pubsub/native/Core_6/Publisher/Publisher.csproj @@ -0,0 +1,11 @@ + + + net48 + Exe + 7.3 + + + + + + \ No newline at end of file diff --git a/samples/pubsub/native/Core_6/Shared/OrderReceived.cs b/samples/pubsub/native/Core_6/Shared/OrderReceived.cs new file mode 100644 index 00000000000..1dd45388f03 --- /dev/null +++ b/samples/pubsub/native/Core_6/Shared/OrderReceived.cs @@ -0,0 +1,8 @@ +using System; +using NServiceBus; + +public class OrderReceived : + IEvent +{ + public Guid OrderId { get; set; } +} \ No newline at end of file diff --git a/samples/pubsub/native/Core_6/Shared/Shared.csproj b/samples/pubsub/native/Core_6/Shared/Shared.csproj new file mode 100644 index 00000000000..30274dea7c6 --- /dev/null +++ b/samples/pubsub/native/Core_6/Shared/Shared.csproj @@ -0,0 +1,9 @@ + + + net48 + 7.3 + + + + + \ No newline at end of file diff --git a/samples/pubsub/native/Core_6/Subscriber/OrderReceivedHandler.cs b/samples/pubsub/native/Core_6/Subscriber/OrderReceivedHandler.cs new file mode 100644 index 00000000000..fc3b6f3eee6 --- /dev/null +++ b/samples/pubsub/native/Core_6/Subscriber/OrderReceivedHandler.cs @@ -0,0 +1,15 @@ +using System.Threading.Tasks; +using NServiceBus; +using NServiceBus.Logging; + +public class OrderReceivedHandler : + IHandleMessages +{ + static ILog log = LogManager.GetLogger(); + + public Task Handle(OrderReceived message, IMessageHandlerContext context) + { + log.Info($"Subscriber has received OrderReceived event with OrderId {message.OrderId}."); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/samples/pubsub/Core_6/Subscriber/Program.cs b/samples/pubsub/native/Core_6/Subscriber/Program.cs similarity index 100% rename from samples/pubsub/Core_6/Subscriber/Program.cs rename to samples/pubsub/native/Core_6/Subscriber/Program.cs diff --git a/samples/pubsub/native/Core_6/Subscriber/Subscriber.csproj b/samples/pubsub/native/Core_6/Subscriber/Subscriber.csproj new file mode 100644 index 00000000000..02110572148 --- /dev/null +++ b/samples/pubsub/native/Core_6/Subscriber/Subscriber.csproj @@ -0,0 +1,11 @@ + + + net48 + Exe + 7.3 + + + + + + \ No newline at end of file diff --git a/samples/pubsub/native/Core_7/PubSub.sln b/samples/pubsub/native/Core_7/PubSub.sln new file mode 100644 index 00000000000..6ff60a46d4f --- /dev/null +++ b/samples/pubsub/native/Core_7/PubSub.sln @@ -0,0 +1,27 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29728.190 +MinimumVisualStudioVersion = 15.0.26730.12 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "Shared\Shared.csproj", "{5686FE6C-A5E3-40D1-A6BD-25F94DA612F8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Publisher", "Publisher\Publisher.csproj", "{7036A49B-359F-4BC7-AFBA-DE3C7AB41986}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Subscriber", "Subscriber\Subscriber.csproj", "{6A699A4E-F2FD-4B71-AF73-199B499482BD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5686FE6C-A5E3-40D1-A6BD-25F94DA612F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5686FE6C-A5E3-40D1-A6BD-25F94DA612F8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7036A49B-359F-4BC7-AFBA-DE3C7AB41986}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7036A49B-359F-4BC7-AFBA-DE3C7AB41986}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6A699A4E-F2FD-4B71-AF73-199B499482BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6A699A4E-F2FD-4B71-AF73-199B499482BD}.Debug|Any CPU.Build.0 = Debug|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/samples/pubsub/native/Core_7/PubSub.sln.DotSettings b/samples/pubsub/native/Core_7/PubSub.sln.DotSettings new file mode 100644 index 00000000000..e0cf84c1382 --- /dev/null +++ b/samples/pubsub/native/Core_7/PubSub.sln.DotSettings @@ -0,0 +1,6 @@ + + ..\..\..\..\tools\Shared.DotSettings + True + True + 1 + \ No newline at end of file diff --git a/samples/pubsub/Core_7/Publisher/Program.cs b/samples/pubsub/native/Core_7/Publisher/Program.cs similarity index 100% rename from samples/pubsub/Core_7/Publisher/Program.cs rename to samples/pubsub/native/Core_7/Publisher/Program.cs diff --git a/samples/pubsub/Core_7/Publisher/Publisher.csproj b/samples/pubsub/native/Core_7/Publisher/Publisher.csproj similarity index 100% rename from samples/pubsub/Core_7/Publisher/Publisher.csproj rename to samples/pubsub/native/Core_7/Publisher/Publisher.csproj diff --git a/samples/pubsub/native/Core_7/Shared/OrderReceived.cs b/samples/pubsub/native/Core_7/Shared/OrderReceived.cs new file mode 100644 index 00000000000..1dd45388f03 --- /dev/null +++ b/samples/pubsub/native/Core_7/Shared/OrderReceived.cs @@ -0,0 +1,8 @@ +using System; +using NServiceBus; + +public class OrderReceived : + IEvent +{ + public Guid OrderId { get; set; } +} \ No newline at end of file diff --git a/samples/pubsub/Core_7/Shared/Shared.csproj b/samples/pubsub/native/Core_7/Shared/Shared.csproj similarity index 100% rename from samples/pubsub/Core_7/Shared/Shared.csproj rename to samples/pubsub/native/Core_7/Shared/Shared.csproj diff --git a/samples/pubsub/native/Core_7/Subscriber/OrderReceivedHandler.cs b/samples/pubsub/native/Core_7/Subscriber/OrderReceivedHandler.cs new file mode 100644 index 00000000000..fc3b6f3eee6 --- /dev/null +++ b/samples/pubsub/native/Core_7/Subscriber/OrderReceivedHandler.cs @@ -0,0 +1,15 @@ +using System.Threading.Tasks; +using NServiceBus; +using NServiceBus.Logging; + +public class OrderReceivedHandler : + IHandleMessages +{ + static ILog log = LogManager.GetLogger(); + + public Task Handle(OrderReceived message, IMessageHandlerContext context) + { + log.Info($"Subscriber has received OrderReceived event with OrderId {message.OrderId}."); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/samples/pubsub/Core_7/Subscriber/Program.cs b/samples/pubsub/native/Core_7/Subscriber/Program.cs similarity index 100% rename from samples/pubsub/Core_7/Subscriber/Program.cs rename to samples/pubsub/native/Core_7/Subscriber/Program.cs diff --git a/samples/pubsub/Core_7/Subscriber/Subscriber.csproj b/samples/pubsub/native/Core_7/Subscriber/Subscriber.csproj similarity index 100% rename from samples/pubsub/Core_7/Subscriber/Subscriber.csproj rename to samples/pubsub/native/Core_7/Subscriber/Subscriber.csproj diff --git a/samples/pubsub/sample.md b/samples/pubsub/native/sample.md similarity index 77% rename from samples/pubsub/sample.md rename to samples/pubsub/native/sample.md index 197d1d5230b..85aaece580f 100644 --- a/samples/pubsub/sample.md +++ b/samples/pubsub/native/sample.md @@ -1,7 +1,7 @@ --- -title: Publish/Subscribe -summary: Publish/Subscribe, fault-tolerant messaging, and durable subscriptions. -reviewed: 2020-07-30 +title: Native Publish/Subscribe +summary: Publish/Subscribe with multicast-enabled transports. +reviewed: 2020-09-28 component: Core redirects: - nservicebus/publish-subscribe-sample @@ -29,7 +29,7 @@ snippet: PublishLoop ## Implementing subscribers -To receive messages from the publisher, the subscribers [must subscribe to the message types](/nservicebus/messaging/publish-subscribe/) they are designed to handle. A subscriber must have a handler for the type of message and a [configuration](/nservicebus/messaging/publish-subscribe/) that tells the endpoint where to send subscriptions for messages for transports that use [message-driven publish/subscribe](/nservicebus/messaging/publish-subscribe/): +To receive messages from the publisher, the subscribers must subscribe to the message types they are designed to handle. * The `Subscriber` handles and subscribes to the `OrderReceived` type. * The handlers in each project are in files that end with the word `Handler` for example `OrderReceivedHandler.cs`. @@ -43,7 +43,7 @@ Click the `1` key repeatedly in the `Publisher` process console window and notic ## Message Flow -The exact message flow may differ between [unicast transports](/transports/types.md#unicast-only-transports) and [broker transports](/transports/types.md#broker-transports). See the [publish-subscribe documentation](/nservicebus/messaging/publish-subscribe/) for further details. +In multicast-enabled transports, the broker handles the subscription mechanism, routing published events to all subscribed endpoints. See the [publish-subscribe documentation](/nservicebus/messaging/publish-subscribe/#mechanics-native) for further details. ## Fault-tolerant messaging @@ -51,4 +51,4 @@ Shut down `Subscriber` by closing its console window. Return to the `Publisher` In Visual Studio, right-click the project of the closed subscriber. Restart it by right-clicking the `Subscriber` project and selecting `Debug` followed by `Start new instance`. -partial: faulttolerance +Note how `Subscriber` immediately receives the messages that were published while it was not running. The publisher safely places the message into the transport in this case LearningTransport without knowledge of the running status of any subscriber. LearningTransport safely places the message in the inbound queue of the subscriber where it awaits handling. Even when processes or machines restart, NServiceBus protects messages from being lost. diff --git a/samples/pubsub/sample_faulttolerance_core_[,6.0).partial.md b/samples/pubsub/sample_faulttolerance_core_[,6.0).partial.md deleted file mode 100644 index c675c95d448..00000000000 --- a/samples/pubsub/sample_faulttolerance_core_[,6.0).partial.md +++ /dev/null @@ -1 +0,0 @@ -Note how `Subscriber` immediately receives the messages that were published while it was not running. The publisher safely places the message into the transport in this case MSMQ without knowledge of the running status of any subscriber. MSMQ safely places the message in the inbound queue of the subscriber where it awaits handling. Even when processes or machines restart, NServiceBus protects messages from being lost. \ No newline at end of file diff --git a/samples/pubsub/sample_faulttolerance_core_[6.0,).partial.md b/samples/pubsub/sample_faulttolerance_core_[6.0,).partial.md deleted file mode 100644 index 7e43f470dab..00000000000 --- a/samples/pubsub/sample_faulttolerance_core_[6.0,).partial.md +++ /dev/null @@ -1 +0,0 @@ -Note how `Subscriber` immediately receives the messages that were published while it was not running. The publisher safely places the message into the transport in this case LearningTransport without knowledge of the running status of any subscriber. LearningTransport safely places the message in the inbound queue of the subscriber where it awaits handling. Even when processes or machines restart, NServiceBus protects messages from being lost. \ No newline at end of file