Hi, this is a day I have been looking forward to for about two years. At least I can put here a pre-release of the Multi-Service Bus Core solution. It is a pre-release because .NET Core 2.0 is still in the preview2 stage. This is, for me, revolutionary code. It is something best I ever did. The C# piece of code that before even .NET Core started supporting WCF Service Host, I could connect between Microsoft Windows, Apple macOS, and GNU Linux. All communication is straightforward. In fact, it uses the same abstraction I prepared in Simple Service Bus. It is dedicated to the IoT, with more than 100k messages per second in a multi-system environment. I tried my best to present the concept graphically, and here is what it looks like.
On the top we have Multi Service Bus and 3 components in the 5 flavors. The Requester, Receiver, and Responder. Reading my blog, you probably know the Simple Service Bus Training where I described all usages. Here is how those components work in your C# code.
namespace TestsSample { using System; using CodingByToDesign.MultiServiceBusCore.Communication.Contracts; using CodingByToDesign.MultiServiceBusCore.Communication; using ProtoBuf; // This is definition of your message protocol // and you need put it in shared assembly for // all components that need to communicate. // Only requirement is to derive from IMessage, // that interface is empty. [ProtoContract] public class MyMessageReq : IMessage { // this is example of entity content. [ProtoMember(0)] public string Uri { get; set; } [ProtoMember(1)] public DateTime TimeStampUtc { get; set; } [ProtoMember(2)] public string HttpMethod { get; set; } } // This is exqmple response message with data. [ProtoContract] public class MyMessageRes : IMessage { // this is example of entity content. [ProtoMember(0)] public string Data { get; set; } } class MultiServiceBusDemoClassInProc { // recevier in-proc private static IReceiver<MyMessageReq> receiver1 = new Receiver<MyMessageReq> { RecieveAction = ReceiveMessage }; // receiver in-proc receive method private static void ReceiveMessage(MyMessageReq message) { // do what you want with received messages here } // requester in-proc private static IRequester<MyMessageReq> requester1 = new Requester<MyMessageReq>(); // in-proc send/request method private static void SendMessageAsync1() { // sending example message to any Receiver<MyMessageReq> requester1.RequestAsync(new MyMessageReq { Uri = "https://iblog.isowa.io", TimeStampUtc = DateTime.UtcNow, HttpMethod = "GET" }); } // receiver in-proc that can response but do not have to private static IReceiver<MyMessageReq, MyMessageRes> receiver2 = new Receiver<MyMessageReq, MyMessageRes> { RecieveAction = ReceiveMessage2 }; // method that receive messages private static void ReceiveMessage2(TransactId id, MyMessageReq mesage) { // you can response back but you do not have to receiver2.ResponseAsync(id, new MyMessageRes { Data = "CodingByToDesign.NET" }); } // requester in-proc that can get responses private static IRequester<MyMessageReq, MyMessageRes> requester2 = new Requester<MyMessageReq, MyMessageRes> { ResponseAction = ReceiveMessageBack2 }; private static void ReceiveMessageBack2(MyMessageRes message) { // do what you want with received response messages here } // in-proc send/request method 2 private static void SendMessageAsync2() { // sending example message requester2.RequestAsync(new MyMessageReq { Uri = "https://iblog.isowa.io", TimeStampUtc = DateTime.UtcNow, HttpMethod = "GET" }, // optional parameter if it is null // ReceiveMessageBack2 will be used new Action<MyMessageRes>( msgRes => { /* use your response message here */ })); } // responder in-proc that have to respond always for messages private static IResponder<MyMessageReq, MyMessageRes> responder3 = new Responder<MyMessageReq, MyMessageRes> { ResponseFunc = RespondMessage }; // method that receive messages and need to create respond message private static MyMessageRes RespondMessage(MyMessageReq message) { return new MyMessageRes { Data = "CodingByToDesign.NET" }; } // requester in-proc that can get responses private static IRequester<MyMessageReq, MyMessageRes> requester3 = new Requester<MyMessageReq, MyMessageRes> { ResponseAction = ReceiveMessageBack3 }; private static void ReceiveMessageBack3(MyMessageRes message) { // do what you want with received response messages here } // in-proc send/request method 3 private static void SendMessageAsync3() { // sending example message requester3.RequestSync(new MyMessageReq { Uri = "https://iblog.isowa.io", TimeStampUtc = DateTime.UtcNow, HttpMethod = "GET" }, // optional parameter if it is null // ReceiveMessageBack3 will be used new Action<MyMessageRes>( msgRes => { /* use your response message here */ })); } } class MultiServiceBusDemoClassInHostOrInNet { // recevier in-host or in-net private static IReceiver<MyMessageReq> receiver1 = new Receiver<MyMessageReq>( netTcpRequesterAddress: "net.tcp://127.0.0.1:27271/Demo" ) { RecieveAction = ReceiveMessage }; // receiver in-host or in-net receive method private static void ReceiveMessage(MyMessageReq message) { // do what you want with received messages here } // requester in-host or in-net private static IRequester<MyMessageReq> requester1 = new Requester<MyMessageReq>( netTcpRequesterAddress: "net.tcp://127.0.0.1:27271/Demo" ); // receive in-host or in-net send/request method private static void SendMessageAsync1() { // sending example message to any Receiver<MyMessageReq> requester1.RequestAsync(new MyMessageReq { Uri = "https://iblog.isowa.io", TimeStampUtc = DateTime.UtcNow, HttpMethod = "GET" }); } // receiver in-host or in-net that can response but do not have to private static IReceiver<MyMessageReq, MyMessageRes> receiver2 = new Receiver<MyMessageReq, MyMessageRes>( netTcpRequesterAddress: "net.tcp://127.0.0.1:27272/Demo" ) { RecieveAction = ReceiveMessage2 }; // method that receive messages private static void ReceiveMessage2(TransactId id, MyMessageReq mesage) { // you can response back but you do not have to receiver2.ResponseAsync(id, new MyMessageRes { Data = "CodingByToDesign.NET" }); } // requester in-host or in-net that can get responses private static IRequester<MyMessageReq, MyMessageRes> requester2 = new Requester<MyMessageReq, MyMessageRes>( netTcpRequesterAddress: "net.tcp://127.0.0.1:27272/Demo" ) { ResponseAction = ReceiveMessageBack2 }; private static void ReceiveMessageBack2(MyMessageRes message) { // do what you want with received response messages here } // in-host or in-net send/request method 2 private static void SendMessageAsync2() { // sending example message requester2.RequestAsync(new MyMessageReq { Uri = "https://iblog.isowa.io", TimeStampUtc = DateTime.UtcNow, HttpMethod = "GET" }, // optional parameter if it is null // ReceiveMessageBack2 will be used new Action<MyMessageRes>( msgRes => { /* use your response message here */ })); } // responder in-host or in-net that have to respond always for messages private static IResponder<MyMessageReq, MyMessageRes> responder3 = new Responder<MyMessageReq, MyMessageRes>( netTcpRequesterAddress: "net.tcp://127.0.0.1:27273/Demo" ) { ResponseFunc = RespondMessage }; // method that receive messages and need to create respond message private static MyMessageRes RespondMessage(MyMessageReq message) { return new MyMessageRes { Data = "CodingByToDesign.NET" }; } // requester in-host or in-net that can get responses private static IRequester<MyMessageReq, MyMessageRes> requester3 = new Requester<MyMessageReq, MyMessageRes>( netTcpRequesterAddress: "net.tcp://127.0.0.1:27273/Demo" ) { ResponseAction = ReceiveMessageBack3 }; private static void ReceiveMessageBack3(MyMessageRes message) { // do what you want with received response messages here } // in-host or in-net send/request method 3 private static void SendMessageAsync3() { // sending example message requester3.RequestSync(new MyMessageReq { Uri = "https://iblog.isowa.io", TimeStampUtc = DateTime.UtcNow, HttpMethod = "GET" }, // optional parameter if it is null // ReceiveMessageBack3 will be used new Action<MyMessageRes>( msgRes => { /* use your response message here */ })); } } class Program { static void Main() { // it is just instantiate new objects, // there is no logic inside the classes yet. var test1 = new MultiServiceBusDemoClassInProc(); var test2 = new MultiServiceBusDemoClassInHostOrInNet(); } } }
This download is obsolete, please go to the post Multi Service Bus Core 2.0 to latest version download for the same code base for .NET 4.7 and .NET Core 2.0.
And here it is… ready to build on .NET Core 2.0… Multi Service Bus Core Source Code (644 downloads).
p ;).
.NET Core 2.0 is ready for production ;-)… you can download it from here: https://www.microsoft.com/net/download/core Thanks! ;-).
If you need uninstall previous version of .net core 2.0 on macOS… here is the uninstall script https://github.com/dotnet/cli/blob/rel/1.0.0/scripts/obtain/uninstall/dotnet-uninstall-pkgs.sh Thanks ;-).
Pingback: Multi Service Bus Core Released - coding by to design
Pingback: Multi Service Bus Core on Raspberry Pi 3 – coding by to design