简体   繁体   English

服务间单向通信的选项

[英]Options for inter-service one-way communication

I'm searching for different options for implementing communication between a service and other services/applications. 我正在寻找用于实现服务与其他服务/应用程序之间的通信的不同选项。

What I would like to do : 我想做的是

I have a service that is constantly running, polling a device connected to a serial port. 我有一项不断运行的服务,轮询连接到串行端口的设备。 At certain points, this service should send a message to interested clients containing data retrieved from the device. 在某些时候,此服务应向感兴趣的客户端发送一条消息,其中包含从设备中检索到的数据。 Data is uncomplicated, most likely just a single string. 数据不复杂,很可能只有一个字符串。

Ideally, the clients would not have to subscribe to receive these messages, which leads me to some sort of event 'broadcast' setup (similar to Windows events). 理想情况下,客户端不必订阅即可接收这些消息,这使我进入了某种事件“广播”设置(类似于Windows事件)。 The message sending process should not block, and does not need a response from any clients (or that there even are any clients for that matter). 消息发送过程不应阻塞,也不需要任何客户端的响应(或与此相关的甚至有任何客户端)。

I've been reading about IPC (COM in particular) and windows events, but am yet to come across something that really fits with what I want to do. 我一直在阅读有关IPC(尤其是COM)和Windows事件的信息,但还没有遇到真正适合我想要做的事情。

So is this possible? 那有可能吗? If so, what technologies should I be using? 如果是这样,我应该使用什么技术? If not, what are some viable communication alternatives? 如果没有,有什么可行的交流选择?

Here's the particulars of the setup: 以下是设置的详细信息:

  • Windows 2000/XP environments Windows 2000 / XP环境
  • 'Server' service is a windows service, using VC++2005 “服务器”服务是Windows服务,使用VC ++ 2005
  • Clients would vary, but always be in the windows environment (usual clients would be VC++6 windows services, VB6 applications) 客户端会有所不同,但始终在Windows环境中(通常,客户端将是VC ++ 6 Windows服务,VB6应用程序)

Any help would be appreciated! 任何帮助,将不胜感激!

Windows supports broadcasting messages, check here . Windows支持广播消息,请在此处检查。 You can SendMessage to HWND_BROADCAST from the service, and receive it in each client. 您可以从服务将SendMessage发送到HWND_BROADCAST ,并在每个客户端中接收它。

There are a number of ways to do a broadcast system, but you'll have to either give up reliability (ie, some messages must be lost) or use a proper subscription system. 广播系统有多种方法,但是您要么必须放弃可靠性(即某些消息必须丢失), 要么使用适当的订阅系统。

If you're willing to give up reliability, you can create a shared memory segment and named manual-reset event object. 如果您愿意放弃可靠性,则可以创建一个共享内存段并命名为“手动重置”事件对象。 When a new message arrives, write it to the shared memory segment, signal the event object, then close the event object and create a new one with a different name (the name should be in the shmem segment somewhere). 当收到新消息时,将其写入共享内存段,向事件对象发出信号,然后关闭事件对象并创建一个具有不同名称的新消息(名称应位于shmem段中的某个位置)。 Clients open the shmem segment, find the current event object, wait for it to be signaled, then read off the message and new event segment. 客户端打开shmem段,找到当前事件对象,等待其发出信号,然后读取消息和新的事件段。

In this option, you must be careful to deal with the case of a client reading at the same time as the shmem segment is updated properly. 在此选项中,您必须小心处理在正确更新shmem段的同时进行客户端读取的情况。 One way to do this is to have two sequence number fields in the shmem segment - one is updated before the new message is written, one after. 一种方法是在shmem段中具有两个序列号字段-一个在写入新消息之前更新,一个在更新之后。 Clients read the second sequence number prior to reading the message, then re-read both sequence numbers after, and check that they are all equal (and discard the message and retry after a delay if they are not). 客户端读取消息之前先读取第二个序列号,然后在此之后重新读取两个序列号,并检查它们是否相等(并丢弃消息,如果不相同则延迟一段时间后重试)。 Be sure to place memory barriers around accesses to these sequence numbers to ensure the compiler does not reorder them! 确保在对这些序列号的访问周围放置内存屏障,以确保编译器不会对它们进行重新排序!

Of course, this is all a bit hairy. 当然,这有点毛。 Named pipes are a lot simpler, but a subscription (of a sort) is required. 命名管道要简单得多,但是需要订阅(某种形式)。 The server calls CreateNamedPipe , then accepts connections with ConnectNamedPipe . 服务器调用CreateNamedPipe ,然后接受与ConnectNamedPipe连接。 Clients use CreateFile to connect to the server's pipe. 客户端使用CreateFile连接到服务器的管道。 The server then just loops to send data (using WriteFile ) to all of its clients. 然后,服务器循环(使用WriteFile )将数据发送到其所有客户端。 Note that you will need to create addititonal instance of the pipe using CreateNamedPipe each time you accept a connection. 请注意,每次接受连接时,都需要使用CreateNamedPipe创建管道的附加实例。 An example of a named pipe server can be found here: http://msdn.microsoft.com/en-us/library/aa365588(v=vs.85).aspx 可以在此处找到命名管道服务器的示例: http : //msdn.microsoft.com/zh-cn/library/aa365588(v=vs.85).aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM