0

我在网上搜索过,但我认为我有更多的理解问题而不是技术问题。通过精读 SO 阅读器,我知道我必须公开我的全部要求,而不是简单地问我的问题......所以。 ..

开发资料:Visual Studio 2010 (..)、C#、目标框架 3.5 客户端配置文件..

我的基本要求:

这是我的要求:我想要一个可以安装在客户端计算机上的可下载软件。该工具将定期从我们使用的精确 ERP 系统中执行一些任务 [下载一些销售数据(发票、订单)。
我不希望用户必须登录才能让我的工具工作(如果计算机重新启动,我希望我的工具仍然启动)。所以在这里,一个标准的 Windows 服务似乎是最好的选择,它带有一个前端应用程序来允许设置一些选项,并查看工作人员的状态。至此,我有了一个 Windows 服务(c# 3.5)和一个前端工具。请注意,此时它对我来说效果很好。在我的服务的 OnStart 方法中,我“启动”我所有的东西(准备文件夹、获取选项、连接到我在云上的远程 SQL Server、验证系统是否良好,然后等待任务,并使用计时器检查用于运行任务)。直到这里,一切都按预期工作。

前端工具和我的 Windows 服务之间的高级通信

现在,我想通过我的前端工具与我的服务交谈/询问一些事情。我想问(“你现在正在运行多少进程”、“你的实际计时器状态是什么”、“你当前正在运行哪些表”、“中止你的所有任务”等等)。我通过向我的 Windows 服务发送自定义命令尝试了一点“自定义命令”,但它确实受到限制:为了知道“您当前正在加载哪些表”问题的答案,我试图写在自定义事件日志,并从我的前端应用程序中检索它,但我发现它并不干净,因为我可能希望从我的工具中获得快速和重复的反馈(例如,看到加载 ONE table 的进度,每 5 次刷新一次秒)。还有写入硬盘驱动器上的文件,

WCF 路径

选项 1 - WCF 服务只是一个通信器,仅此而已。

因此,正如在 Internet 上发现的那样,我开始查看托管 WCF 服务选项。所以首先,我只在我的主 Windows 服务中添加了一个简单而温和的 WCF 服务库。该子 WCF 服务只会响应来自前端工具的复杂问题,然后向其创建者(主要 Windows 服务)寻求响应。我的基本设置工作 -> 在我的 Windows Servbice 的 OnStart 中,我启动了我所有的业务,并启动了(HostService)我的 WCF 服务来监听。但是我看不到任何方法可以在我的 Windows 服务和我的 WCF 服务之间建立完整的链接(以便能够访问主要的服务复杂信息)。静态方法?将主要的“状态”类传递给 WCF 服务,但是如何?..

选项 2 - Wcf 服务就是一切。

然后,我尝试将我的所有代码移动到我的 WCF 服务中,说“好的,如果只有一个可以做到这一点,为什么要有 2 个程序集”。因此,在我的基本 Windows 服务的 OnStart 中,不再启动我的业务内容。仅启动子 WCFServices。在概念层面上一切似乎都很好。但是我怎么能说“好的,WCF 服务,开始倾听,并启动业务”?我没有找到关于 WCF 服务的“启动时启动代码”的信息。在网络上,我看到很多“WCF 服务主要用于‘随叫随到’。但我希望 WCF 服务通过计时器完成我所有的工作(加载表、将它们上传到 cload 等...)并且能够与前端工具对话。我必须在主 Windows 服务中创建 WCF 服务,

所以,我的问题: 1 - 我的架构有意义吗?2 - WindowsService->WCFService 托管对我的要求有意义吗?3 - 我应该将所有代码移动到 WCF 服务库吗?或不

多谢!

西蒙


编辑:

谢谢FerretallicA!

老实说,我更喜欢把所有东西都分开。所以我喜欢你将我的类的引用传递给我的 WCF 服务的想法。

只是为了更完整的东西,这是我的主要 Windows 服务的 OnStart 方法:

注意:(很多代码来自:How to: Host a WCF Service in a Managed Windows Service

   protected override void OnStart(string[] args)
    {
        //The MyMainClass is global to my service.  
        MyMainClass = new DailyExtraction_MainClass();

        //initiating the worker (setting the timer ticks,  basic connexion,etc....)
        MyMainClass.Initialiser_Robot_Extracteur(); 


        //Write some log through my Worker 
        MyMainClass.MyLogExecution.WriteLog(" - End of OnStart()");

        **//Here is the WCF Sub-service creation**
        try
        {
            if (myWCFServiceHost != null)
            {
                myWCFServiceHost.Close();
            }

            // Create a ServiceHost for my class type and .
            myWCFServiceHost = new ServiceHost(typeof(DailyExtractionUtils.CloudBI_Communicator));

            // Open the ServiceHostBase to create listeners and start 
            // listening for messages.
            myWCFServiceHost.Open();


        }
        catch (Exception ex)
        {
            MyMainClass.MyLogExecution.WriteLog(" - Error while trying to create the WCF Service");
        }
    }

所以,我试图弄清楚我必须在哪里将引用传递给我的“MyMainClass”类。

注意:我刚刚重新搜索了您的想法“如何传递对子 wcf 服务的引用”,我发现:SO question - WCF call that references Windows Service。稍后我将深入阅读。

4

2 回答 2

0
  1. 这在您的情况下是否可行将取决于您的服务设计,但我会考虑使用您提供的整体设计将服务 A 暴露给 B 的两种通用方法:

    • 将主服务实例的引用传递给构造函数中的 WCF/监控服务
    • 如果使用 Castle Windsor 之类的东西,请将您的主服务注册为单例,以便监控服务可以从各个点访问主服务实例
  2. 没关系

  3. 根本没有必要,但根据主要服务的性质,以与主要功能一致的方式公开监视功能可能是有意义的。

于 2013-07-17T12:23:25.657 回答
0

[我意识到这个帖子比较老,但我自己阅读了这些类型的问答环节以获得指导;其他人可能会跟进,因为他们有类似的担忧。]

通常在最初的平台设计中,我会建议以下经验法则:从头开始。换句话说,想象你自己实现了这个并询问你将在哪里托管它如果您在许多情况下将其托管在云中,那么与最终用户对话的部分可以增加或减少实例数量,以根据需求进行扩展。在这种情况下,您可能有一个或两个实际拥有数据的后端分析部分实例。如果我认为它可能稍后会托管在云中的某个地方,我会赞成上面选项 1 中的分离方法。

另外,我想我会考虑诸如连接到 ERP 系统本身的任务点之类的事情。这部分是否需要一个简单的、本机 Microsoft ODBC 连接,还是需要一些第三方连接,如 QODBC 或类似的?是否为此按工作站收费?其次,年复一年升级ERP系统,是否需要升级通讯部分?(想象一下,必须升级所有客户端软件才能跟上。)出于这些原因,我更喜欢将这部分移动到本地或云托管的服务器上。您将使用一台集中式服务器连接到 ERP 系统,并将分析的数据公开给您制作的其他软件。

因此,我认为我将采用的实现将是在本地服务器上运行的 WCF 服务,并结合最终用户命令运行的客户端部分。最终用户部分不是服务,因为它不需要。

于 2014-11-07T16:13:42.223 回答