使用 Obvs 连接简单的客户端/服务器






4.50/5 (8投票s)
本文说明了如何开始使用 Obvs 作为简单客户端和服务器之间的消息传递层。
引言
在本文中,我想向所有有兴趣尝试 Obvs 的人展示,如何轻松快速地将他们的进程连接在一起,并通过他们选择的传输方式发送和接收消息,而只需很少的代码。下面我将用 C# 创建一个包含简单客户端和服务器的示例解决方案。
背景
任何进行领域驱动设计、构建响应式应用程序或设计“微服务”的人,在某些时候都可能会发现自己希望将应用程序分布在两个或更多进程中。在进程之间发送和接收消息可能需要为每条新消息或服务编写大量样板代码。
Obvs 是一个轻量级库,它封装了特定传输的复杂性,并允许您用很少的代码将服务连接起来。它是我在编写内部应用程序时创建的,并已投入生产使用。代码在 GitHub 上开源,您可以在 NuGet 上找到相关软件包 https://nuget.net.cn/packages?q=obvs。
Obvs 特性
- 简单的基于 RX 的接口,用于发布/订阅
- 基于约定的消息传递,按服务划分主题/队列
- 在单个主题/队列上复用多种消息类型
- 为每种类型动态创建反序列化器
- 在单独的通道上进行异步错误处理
- 易于扩展和定制,允许与外部系统集成
- 流畅的代码配置
- 支持 ActiveMQ 和 NetMQ 传输
- 提供 XML、JSON 和 ProtoBuf 的序列化
先决条件
要继续,您需要 Visual Studio、用于 NuGet.org 的互联网访问以及要连接的 ActiveMQ 代理。如果您需要,可以自行下载并安装它,只需遵循这些说明 https://activemq.apache.ac.cn/getting-started.html#GettingStarted-InstallationProcedureforWindows
创建服务器
打开一个新的 Visual Studio 解决方案,创建一个名为“Server”的新命令行项目。您的服务器将接收命令并发送事件。它还将支持请求/响应。
打开程序包管理器控制台并键入
- install-package Obvs.ActiveMQ
- install-package Obvs.Serialization.Json
现在应该已安装所需的程序包并已引用到您的 Server 项目中。在本示例中,我们将使用 ActiveMQ 作为传输协议,JSON 作为序列化格式。
创建您的第一个消息契约
创建一个名为“Contracts”的新类库,我们将用它来存储所有消息类型。
现在打开程序包管理器控制台并键入
- install-package Obvs -project Contracts
您需要的第一种类型是一个接口,用于标记消息属于特定服务,我们将它命名为 IExampleServiceMessage,它将扩展 Obvs.Types.IMessage。
public interface IExampleServiceMessage : IMessage {}
接下来,我们将创建几个命令发送到服务器。在 Contracts 项目中创建一个名为 Commands 的新文件夹,并添加一个名为 ChangeName 的新类,该类实现 Obvs.Types.ICommand 和您的 IExampleServiceMessage 接口。添加一个名为 Name 的字符串属性。
public class ChangeName : ICommand, IExampleServiceMessage { public string Name { get; set; } public override string ToString() { return string.Format("ChangeName = {0}", Name); } }
我们希望服务器通过事件响应命令,因此创建一个名为 Events 的文件夹,并创建一个名为 NameChanged 的新类,该类实现 Obvs.Types.IEvent 和您的 IExampleServiceMessage 接口。同样,添加一个名为 Name 的字符串属性。
public class NameChanged : IEvent, IExampleServiceMessage { public string Name { get; set; } public override string ToString() { return string.Format("NameChanged = {0}", Name); } }
配置您的 ServiceBus
回到服务器,在您的 Program.cs 类中,添加一个静态私有函数来创建一个具有单个终结点的 Obvs.ServiceBus。这可以通过服务名称、要连接的 ActiveMQ 代理和序列化格式进行流畅配置。创建终结点AsServer 意味着它将接收命令并发布事件。请记住,如果您未在本地计算机上安装代理,请更改代理 URI。
private static IServiceBus CreateServiceBus() { return ServiceBus.Configure() .WithActiveMQEndpoints<IExampleServiceMessage>() .Named("Obvs.ExampleService") .ConnectToBroker("tcp://:61616") .SerializedAsJson() .AsServer() .Create(); }
使用此函数在 Main 方法中创建一个 ServiceBus,订阅 ChangeName 命令,并在收到该命令时发布 NameChanged 事件。您可以通过使用 Rx 操作符OfType<> 来实现此目的。此外,我们还希望将收到的任何命令打印到控制台。
serviceBus.Commands .OfType<ChangeName>() .Subscribe(command => serviceBus.Publish(new NameChanged { Name = command.Name })); serviceBusClient.Commands.Subscribe(Console.WriteLine);
为确保您的服务器在收到命令之前不会退出,请使用 Console.ReadLine。
创建您的客户端
现在我们需要一种方法来发送 ChangeName 命令,因此让我们创建客户端。创建另一个名为“Client”的命令行项目,并引用“Contracts”项目。
现在打开程序包管理器控制台并键入
- install-package Obvs.ActiveMQ -project Client
- install-package Obvs.Serialization.Json -project Client
您的客户端将需要一个 ServiceBusClient,因此创建一个像我们在 Server 中那样创建,但指定 AsClient 而不是 AsServer,以表明我们将从此服务发送命令并接收事件。ServiceBusClient 的接口方法集有所减少,这限制了客户端接收命令或发布事件。
private static IServiceBusClient CreateServiceBus() { return ServiceBus.Configure() .WithActiveMQEndpoints<IExampleServiceMessage>() .Named("Obvs.ExampleService") .ConnectToBroker("tcp://:61616") .SerializedAsJson() .AsClient() .CreateClient(); }
现在,在 Client 的 Main 方法中,创建一个 ServiceBusClient,并使用它发送命令并打印接收到的事件。
serviceBusClient.Events.Subscribe(Console.WriteLine); serviceBusClient.Send(new ChangeName {Name = "Chris"});
记住使用 Console.ReadLine 来阻止程序退出。现在,先启动您的服务器,然后再启动您的客户端。您应该会看到它们发送和接收命令!
添加更多消息类型
现在您已经设置好了一切,发送和接收任何其他消息类型无需额外代码。您只需创建类,用正确的接口装饰它们,然后在客户端和服务器中使用它们。Obvs 将发现您程序集中的消息类型,负责对它们进行序列化和反序列化,将它们复用到命名合理的 ActiveMQ 主题上,并通常确保它们到达正确的位置。
添加更多服务
添加更多服务同样简单,只需创建一个新接口来识别属于该服务 Thus 消息,并使用流畅的配置接口来配置您的 ServiceBus,为其服务提供一个终结点。例如:
private static IServiceBus CreateServiceBus() { return ServiceBus.Configure() .WithActiveMQEndpoints<IExampleService1Message>() .Named("Obvs.ExampleService1") .ConnectToBroker("tcp://:61616") .SerializedAsJson() .AsServer() .WithActiveMQEndpoints<IExampleService2Message>() .Named("Obvs.ExampleService2") .ConnectToBroker("tcp://:61616") .SerializedAsJson() .AsServer() .Create(); }
结论
我希望您发现本文对您有所帮助,并考虑在您的项目中也使用 Obvs。我包含了示例应用程序的完整源代码,其中还包括了请求/响应的示例。请在 GitHub 上查看 Obvs 的代码 https://github.com/inter8ection/Obvs。非常欢迎所有评论、贡献和反馈!