跨应用程序通信(C#)
我正在开发一种软件解决方案,用于在同一服务器上运行的一组应用程序。
这些应用程序松散相关,并共享事件日志。我们遇到的问题是性能,每个应用程序每次需要记录事件时都会调用数据库。
我想做的是通过删除应用程序对数据库的直接调用来解耦整个过程,并通过在计算机上运行的服务路由它们,该服务的唯一目的是处理来自计算机上多个应用程序的事件。
最终我的目标是在“事件”辅助对象中实现某种系统,该系统将允许那些对象直接与“事件”服务通信。
我的第一直觉是使用典型的“事件”,但从我所做的研究来看,不可能调用一个进程中的事件在另一个进程中处理。
作为我研究的一部分,我遇到了监听另一个应用程序中的事件并且使用 SendMessage 进行 C# Win32 消息传送。
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,然后配置该服务以在本地主机上使用命名管道。
提供的所有帮助
跟进
感谢您为任何可能感兴趣的人 。这工作得很漂亮。 net.pipe 处于活动状态,我能够创建事件并将它们从多个应用程序发送到服务,而处理时间很少或根本没有。
wcf 服务封装在一个非常简单的 Windows 服务中,只需打开服务管道即可。在客户端,我能够轻松地发现并实施该服务。我所要做的就是调用客户端类,它会在数据库中实时显示我的事件。
再次感谢。
I'm working on a software solution to for a group of applications running on the same server.
The applications are loosely related, and share an event log. The problem that we are running into is performance, with each application making calls to the database every time they need to log an event.
What I'm trying to do is decouple the entire process by removing the applications direct calls to the database, and routing them through a service running on the machine whos sole purpose is processing events from the multiple applications on the machine.
Ultimately my goal is to implement some sort of system in the "Event" Helper Object that would allow those objects to communicate directly with the "Event" Service.
My first instinct was to use your typical "event", but it would appear from the research that I've done that it is not possible to invoke an event in one process to be handled in another process.
As a part of my research I came across Listen for events in another application and C# Win32 messaging with SendMessage.
Sendmessage looks like a promising solution, but I wanted to be sure so I spoke with one of my colleagues who was close to the project (the original developer who was moved on to a new project before the completion of this one) and he imparted some additional information as to the situation. They had apparently attmped to use WCF and build it as a web service. This probably would have worked except for the location and security level of the server itself.
He believes it MAY be possible to implement a WCF system at the OS level without having to use it in a web service environment.
My question is... "Is using WCF possible at the OS level?" and "Which of the options listed would be the most efficent under the scenario?" Keeping in mind that this MUST be decoupled and the applications cannot have any interaction with the event log in the database itself.
WCF Update:
So I started putting something together and this is what I came up with..
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();
}
}
}
But there is a problem. This line:
Uri baseAddress = new Uri("http://localhost:8080/SelfHost");
I guarantee that the server will not allow the service to register that local address (its been tried already and it was a flop).
So my new question is... "Is there a way around that that does not involve changing configuration settings on the server itself?"
MSMQ Update:
This is deffinately an option but... [pregnant pause] We do use the message queue for other pieces of functionality. My only hesitation is the overhead. I'd rather that it was completely decoupled I'm looking for an application to application solution. I'd rather that the service was "listening" instead of going to get.
Finale
I did a lot more research and I've decided that using WCF is in my best interest.
As a part of the windows service I plan on adding an app.config for the event logging service and then configuring the service to use named pipes over localhost.
thanks for all the help
Follow-Up
For anyone who might be interested. This works beautifuly. The net.pipe is active and I am able to create events and send them to the service from multiple apps with little or no processing time.
The wcf service is encased in a very simple windows service that simply opens the service pipe. on the client side i was able to discover and implement the service easily. All i have to do is make a call to the client class and it shows my events in real time in the database.
Thanks again.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您可以在没有 Web 托管和 IIS 的情况下执行 WCF,这些 WCF 服务将是 TcpIp 并且将在您的本地网络中正常工作,这样您就没有 SOAP 序列化。
您还可以使用的一种方法(我在一家拥有多服务器多层分布式应用程序的前公司中确实使用过),是让您的事件帮助程序对象简单地将消息排队到将驻留在某个服务器上的 MSMQ,此方法效果很好,因为它不像 SendMessage 那样同步,因此即使侦听器应用程序不可用、未运行或只是繁忙,您的应用程序也可以正常工作。
然后你可以在该机器上运行一个 Windows 服务(我们过去称之为 LoggingManager ),它从队列中查看消息并以自己的速度和平静在数据库中创建日志;-)
you could do WCF without web hosting and without IIS, those WCF services will be TcpIp and will work in your local network with no problems, in this way you don't have SOAP Serialization.
One approach you could also use ( and I did use in a former company where we had a multi server multi-tier distributed application ), is to make your Event Helper Object to simply queue messages to a MSMQ which will reside on a certain server, this method works very well because is not synchronous like SendMessage so your application works even if the listener application is not available and not running or simply busy.
Then you could have a windows Service running on that machine ( we used to call it LoggingManager ) which peeks the messages from the queue and created the log in the databases at his own speed and peace ;-)
我以前遇到过这个要求。解决方案通常涉及将“事件”写入“队列”,并使用专用服务读取队列并将其发布到数据库。 WCF支持MSMQ,是一个不错的选择。
I've come across this requirement before. The solution usually involves writing the "event" to a "queue" and having a dedicated service reading the queue and posting to the database. WCF supports MSMQ and is a good choice.
你向我描述的听起来很像服务总线架构——而我对这个主题知之甚少。或者我完全错了?如果没有,请查看 NServiceBus (http://www.nservicebus.com/) 等产品。也许这会对你有帮助?
问候,
莫滕
You are describing to me, what sounds a lot like a service bus architecture - without me knowing a terrible great deal about the subject. Or am I completely wrong? If not, take a look at producks such as NServiceBus (http://www.nservicebus.com/). Maybe that will help you?
Regards,
Morten
我建议使用 WCF。出于安全目的,它可以轻松配置为仅接受来自本地计算机的请求,并且比 SendMessage 或直接使用 NamedPipes 或 Ports 之类的东西更有利于友好的 .NET 代码。
I'd suggest using WCF. It can be easily configured to only accept requests from the local machine for security purposes, and is more conducive to friendly .NET code then something like SendMessage or using NamedPipes or Ports directly.
如果您喜欢 SendMessage 概念,请查看我们的 MsgConnect 产品,它为之间的通信提供了相同的方法在相同或不同系统上运行的进程。 MsgConnect 是跨平台的,不仅限于.NET。
WCF 也可以是一个选项,尽管 MsgConnect 的 API 可能更简单且更易于管理(因为您还可以获得源代码和支持)。
If you like SendMessage concept, take a look at our MsgConnect product, which offers the same approach for communications between processes running on the same or on different systems. MsgConnect is cross-platofrm and is not limited to .NET.
WCF can be an option as well, though MsgConnect's API is probably simpler and easier to manage (as you also get the source code and support).
我认为您需要一个自托管的 WCF 应用程序。 这是一本关于 WCF 的好书,第四章讨论了自托管。
I think you want a self-hosted WCF application. This is a great book on WCF and chapter four talks about self-hosting.
除了这些其他答案之外:您的“事件”助手可能是 自定义跟踪组件您在各种应用程序中注册。这样做,您不必在应用程序中直接引用“事件”帮助器目标,而只需将事件记录到配置的跟踪输出中。
Just in addition to those other answers: Your "Event" Helper could be a custom tracing component you register in your various applications. Doing so you wouldn't have to directly reference a "Event" Helper target in your applications but just log your events to the configured trace output.