服务间单向通信的选项

发布于 2024-10-17 00:58:43 字数 564 浏览 1 评论 0原文

我正在寻找用于实现服务与其他服务/应用程序之间通信的不同选项。

我想做的

我有一个不断运行的服务,轮询连接到串行端口的设备。在某些时候,该服务应该向感兴趣的客户端发送一条消息,其中包含从设备检索的数据。数据并不复杂,很可能只是一个字符串。

理想情况下,客户端不必订阅即可接收这些消息,这导致我进行某种事件“广播”设置(类似于 Windows 事件)。消息发送过程不应阻塞,并且不需要任何客户端的响应(或者甚至不需要任何客户端)。

我一直在阅读有关 IPC(特别是 COM)和 Windows 事件的内容,但尚未遇到真正适合我想做的事情。

那么这可能吗?如果是这样,我应该使用什么技术?如果没有,有哪些可行的沟通替代方案?

以下是设置的细节:

  • Windows 2000/XP 环境
  • “服务器”服务是 Windows 服务,使用 VC++2005
  • 客户端会有所不同,但始终处于 Windows 环境中(通常客户端是 VC++6 Windows 服务、VB6应用程序)

任何帮助将不胜感激!

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). 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.

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
  • 'Server' service is a windows service, using VC++2005
  • Clients would vary, but always be in the windows environment (usual clients would be VC++6 windows services, VB6 applications)

Any help would be appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

决绝 2024-10-24 00:58:43

Windows supports broadcasting messages, check here. You can SendMessage to HWND_BROADCAST from the service, and receive it in each client.

走过海棠暮 2024-10-24 00:58:43

构建广播系统的方法有很多种,但您必须要么放弃可靠性(即,某些消息必须丢失),要么使用适当的订阅系统。

如果您愿意放弃可靠性,您可以创建一个共享内存段并命名为手动重置事件对象。当新消息到达时,将其写入共享内存段,向事件对象发出信号,然后关闭事件对象并创建一个具有不同名称的新消息(该名称应该位于 shmem 段中的某处)。客户端打开 shmem 段,找到当前事件对象,等待它收到信号,然后读取消息和新事件段。

在此选项中,您必须小心处理在 shmem 段正确更新的同时客户端读取的情况。实现此目的的一种方法是在 shmem 段中有两个序列号字段 - 一个在写入新消息之前更新,一个在写入之后更新。客户端在读取消息之前读取第二序列号,然后重新读取这两个序列号,并检查它们是否全部相等(并丢弃消息并在之后重试)如果不是,则延迟)。请务必在对这些序列号的访问周围放置内存屏障,以确保编译器不会对它们重新排序!

当然,这一切都有点毛茸茸的。 命名管道要简单得多,但需要订阅(某种形式)。服务器调用 CreateNamedPipe ,然后接受与 ConnectNamedPipe。客户端使用 CreateFile< /a> 连接到服务器的管道。然后,服务器循环将数据(使用WriteFile)发送到所有客户端。请注意,每次接受连接时,您都需要使用 CreateNamedPipe 创建管道的附加实例。可以在此处找到命名管道服务器的示例: http://msdn.microsoft.com/en-us/library/aa365588(v=vs.85).aspx

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). 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.

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. 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. 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. Clients use CreateFile to connect to the server's pipe. The server then just loops to send data (using WriteFile) to all of its clients. Note that you will need to create addititonal instance of the pipe using CreateNamedPipe each time you accept a connection. An example of a named pipe server can be found here: http://msdn.microsoft.com/en-us/library/aa365588(v=vs.85).aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文