【问题标题】:WCF: Accessing the service instance from the serverWCF:从服务器访问服务实例
【发布时间】:2010-11-08 21:05:56
【问题描述】:

上下文:

我需要开发一个监控服务器来监控我们的一些应用程序(这些应用程序在 c# 中)。所以我决定用 WCF 开发这个似乎适合我需要的系统。

这些应用程序必须在启动时将自己注册到监控服务器。之后,监控服务器可以调用这些应用程序的 Start 或 Stop 方法。

一切都完全在同一台机器上执行,不需要远程执行。

所以我开发了一个很好的原型,一切正常。每个应用程序都将自己注册到监控服务器。

问题:

ApplicationRegistrationService(见下面的代码)是监控服务的实现,由于ServiceBehavior属性,它是一个单例实例。

这是我的问题:我想访问每个示例中的 ApplicationRegistrationService 的内容,即从我的服务器连接的应用程序的数量(示例中为 ConsoleMonitoringServer)。但是,我不确定如何实现这一点。

我是否需要像在客户端 (ConsoleClient) 中那样在我的服务器中为服务创建一个通道,或者是否存在更好的方法来实现这一点?

代码:

出于这个问题的目的,代码非常简化:

//The callback contract interface
public interface IApplicationAction
{
    [OperationContract(IsOneWay = true)]
    void Stop();

    [OperationContract(IsOneWay = true)]
    void Start();
}

[ServiceContract(SessionMode = SessionMode.Required, 
    CallbackContract = typeof(IApplicationAction))]
public interface IApplicationRegistration
{
    [OperationContract]
    void Register(Guid guid, string name);

    [OperationContract]
    void Unregister(Guid guid);
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, 
    ConcurrencyMode = ConcurrencyMode.Multiple)]
public class ApplicationRegistrationService : IApplicationRegistration
{
    //IApplicationRegistration Implementation
}

public class ApplicationAction : IApplicationAction
{
    //IApplicationAction Implementation
}

此示例的控制台应用程序

class ConsoleClient
{
    static void Main(string[] args)
    {
        ApplicationAction actions = new ApplicationAction();

        DuplexChannelFactory<IApplicationRegistration> appRegPipeFactory =
            new DuplexChannelFactory<IApplicationRegistration>(actions,
            new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/AppReg"));

        IApplicationRegistration proxy = appRegPipeFactory.CreateChannel();
        proxy.Register(Guid.Empty, "ThisClientName");

        //Do stuffs
    }
}

此示例的控制台服务器

class ConsoleMonitoringServer
{
    static void Main(string[] args)
    {
        using (ServiceHost host = new ServiceHost(typeof(ApplicationRegistrationService),
            new Uri[]{ new Uri("net.pipe://localhost")}))
        {
            host.AddServiceEndpoint(typeof(IApplicationRegistration), 
                new NetNamedPipeBinding(), "AppReg");

            host.Open();

            //Wait until some write something in the console
            Console.ReadLine();

            host.Close();
        }
    }
}

【问题讨论】:

    标签: c# wcf client-server


    【解决方案1】:

    最后,我找到了答案,这很容易。我只需要创建服务实例并将引用传递给ServiceHost的构造函数。

    所以我需要替换以下代码:

    using (ServiceHost host = new ServiceHost(typeof(ApplicationRegistrationService),
                    new Uri[]{ new Uri("net.pipe://localhost")}))
    

    作者:

    ApplicationRegistrationService myService = new ApplicationRegistrationService();
    
    using (ServiceHost host = new ServiceHost(myService,
                    new Uri[]{ new Uri("net.pipe://localhost")}))
    

    【讨论】:

    • 仅供参考:这只适用于 InstanceContextMode = InstanceContextMode.Single。
    【解决方案2】:

    如果您的意思是希望在监控服务和注册服务或节点之间进行双向通信,那么您可能应该在 WCF 中使用双向通信,也称为双工通信。很酷的东西。

    http://www.codeproject.com/KB/WCF/WCF_Duplex_UI_Threads.aspx

    【讨论】:

    • 感谢您的链接,但我已经在我的代码中做了类似的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-17
    • 2017-01-15
    • 1970-01-01
    • 2018-01-22
    相关资源
    最近更新 更多