跨应用程序通信(C#)

时间:2011-02-21 20:31:48

标签: c# wcf ipc msmq

我正在为同一台服务器上运行的一组应用程序开发软件解决方案。

应用程序松散相关,并共享事件日志。我们遇到的问题是性能,每个应用程序在每次需要记录事件时都会调用数据库。

我要做的是通过删除应用程序直接调用数据库来解耦整个过程,并通过在机器上运行的服务来路由它们,而这些服务的唯一目的是处理来自机器上多个应用程序的事件。 / p>

Event Helper Service - Image

最终我的目标是在“事件”助手对象中实现某种系统,允许这些对象直接与“事件”服务进行通信。

我的第一直觉是使用你典型的“事件”,但是从我已经完成的研究中可以看出,在一个进程中调用一个事件是不可能在另一个进程中处理的。

作为我研究的一部分,我遇到了Listen for events in another applicationC# Win32 messaging with SendMessage

Sendmessage看起来是一个很有前途的解决方案,但我想确定,所以我与一位接近项目的同事(原始开发人员在完成此项目之前转移到新项目)进行了交谈。他提供了一些有关情况的补充资料。他们显然倾向于使用WCF并将其构建为Web服务。除了服务器本身的位置和安全级别之外,这可能会有效。

他认为可以在操作系统级别实现WCF系统,而无需在Web服务环境中使用它。

我的问题是......“在操作系统级别可以使用WCF吗?”并且“在这种情况下,列出哪些选项最有效?”请记住,这必须解耦,应用程序不能与数据库本身的事件日志进行任何交互。

WCF更新:

所以我开始把东西放在一起,这就是我想出的......

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace SelfHost
{
    [ServiceContract]
    public interface ISelfHostingService
    {
        [OperationContract]
        string SelfHost(string name);
    }
    public class SelfHostingService : ISelfHostingService
    {
        public string SelfHost(string name)
        {
            return string.Format("Hello, {0}", name);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Uri baseAddress = new Uri("http://localhost:8080/SelfHost");
            ServiceHost host = new ServiceHost(typeof(SelfHostingService), baseAddress);
            host.AddServiceEndpoint(typeof(SelfHost.ISelfHostingService), new BasicHttpBinding(), baseAddress);
                host.Open();
                Console.WriteLine("The service is ready at {0}", baseAddress);
                Console.WriteLine("Press <Enter> to stop the service.");
                Console.ReadLine();
        }
    }
}

但是有一个问题。这一行:

Uri baseAddress = new Uri("http://localhost:8080/SelfHost");

我保证服务器不会允许服务注册该本地地址(已经尝试过,而且是翻转)。

所以我的新问题是......“有没有办法解决服务器本身不改变配置设置的问题?”

MSMQ更新:

这是一个选项,但是...... [怀孕暂停]我们确实将消息队列用于其他功能。我唯一的犹豫是开销。我宁愿它完全解耦我正在寻找应用程序解决方案的应用程序。我宁愿这项服务是“倾听”而不是去获得。

终曲

我做了很多研究,我决定使用WCF符合我的最佳利益。 作为Windows服务的一部分,我计划为事件记录服务添加app.config,然后配置服务以在localhost上使用命名管道。

感谢所有帮助

后续

对于任何可能感兴趣的人。这很美妙。 net.pipe处于活动状态,我可以创建事件并将其从多个应用程序发送到服务,几乎没有处理时间。

wcf服务包含在一个非常简单的Windows服务中,只需打开服务管道即可。在客户端,我能够轻松地发现和实施该服务。我所要做的就是调用客户端类,它会在数据库中实时显示我的事件。

再次感谢。

7 个答案:

答案 0 :(得分:3)

你可以在没有虚拟主机的情况下进行WCF,没有IIS,那些WCF服务将是TcpIp,并且可以在本地网络中正常运行,没有任何问题,这样就没有SOAP序列化。

您也可以使用的一种方法(我在曾经有多服务器多层分布式应用程序的公司中使用过)是让您的事件助手对象简单地将消息排队到MSMQ,MSMQ将驻留在某个服务器,这种方法非常有效,因为它不像SendMessage那样是同步的,所以即使监听器应用程序不可用而且没有运行或只是忙碌,你的应用程序也能工作。

然后你可以在那台机器上运行一个Windows服务(我们以前称之为LoggingManager),它从队列中查看消息并以自己的速度和平创建数据库中的日志; - )

答案 1 :(得分:2)

我之前遇到过这个要求。该解决方案通常涉及将“事件”写入“队列”并具有读取队列并发布到数据库的专用服务。 WCF支持MSMQ,是一个不错的选择。

答案 2 :(得分:2)

你在向我描述,听起来很像服务总线架构 - 没有我知道关于这个主题的可怕的很多。还是我完全错了?如果没有,请查看NServiceBus(http://www.nservicebus.com/)等产品。也许这会对你有帮助吗?

此致 的Morten

答案 3 :(得分:0)

我建议使用WCF。它可以很容易地配置为仅接受来自本地机器的请求以用于安全目的,并且更有利于友好的.NET代码,然后是SendMessage或直接使用NamedPipes或Ports。

答案 4 :(得分:0)

如果您喜欢SendMessage概念,请查看我们的MsgConnect产品,该产品为在相同或不同系统上运行的进程之间的通信提供相同的方法。 MsgConnect是cross-platofrm,不仅限于.NET。

WCF也可以是一个选项,尽管MsgConnect的API可能更简单,更易于管理(因为您还可以获得源代码和支持)。

答案 5 :(得分:0)

我认为你想要一个自托管的WCF应用程序。 This是关于WCF的好书,第四章是关于自托管的。

答案 6 :(得分:0)

除了其他答案之外:您的“事件”助手可能是您在各种应用程序中注册的custom tracing component。这样做您不必在应用程序中直接引用“事件”帮助程序目标,而只需将事件记录到配置的跟踪输出中。