WCF一个服务实例的多个通道

本文关键字:实例 通道 服务 一个 WCF | 更新日期: 2023-09-27 18:18:01

这是我的服务器应用程序代码:

[ServiceContract]
public interface IFirst
{
    [OperationContract]
    void First();
}
[ServiceContract]
public interface ISecond
{
    [OperationContract]
    void Second();
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
class Service : IFirst, ISecond
{
    static int count = 0;
    int serviceID;
    public Service()
    {
        serviceID = ++count;
        Console.WriteLine("Service {0} created.", serviceID);
    }
    public void First()
    {
        Console.WriteLine("First function. ServiceID: {0}", serviceID);
    }
    public void Second()
    {
        Console.WriteLine("Second function. ServiceID: {0}", serviceID);
    }
}
class Server
{
    static void Main(string[] args)
    {
        ServiceHost host = new ServiceHost(typeof(Service), new Uri("net.tcp://localhost:8000"));
        NetTcpBinding binding = new NetTcpBinding();
        host.AddServiceEndpoint(typeof(IFirst), binding, "");
        host.AddServiceEndpoint(typeof(ISecond), binding, "");
        host.Open();
        Console.WriteLine("Successfully opened port 8000.");
        Console.ReadLine();          
        host.Close();
    }
}

和客户端:

class Client
{
    static void Main(string[] args)
    {
        ChannelFactory<IFirst> firstFactory = new ChannelFactory<IFirst>(new NetTcpBinding(), new EndpointAddress("net.tcp://localhost:8000"));
        IFirst iForst = firstFactory.CreateChannel();
        iForst.First();
        ChannelFactory<ISecond> secondFactory = new ChannelFactory<ISecond>(new NetTcpBinding(), new EndpointAddress("net.tcp://localhost:8000"));
        ISecond iSecond = secondFactory.CreateChannel();
        iSecond.Second();
        Console.ReadLine();
    }
}

当我运行它时,我得到输出:

Successfully opened port 8000.
Service 1 created.
First function. ServiceID: 1
Service 2 created.
Second function. ServiceID: 2
在我的例子中,服务器创建了两个Service实例。我想做的是为第一个服务实例调用第二个函数

WCF一个服务实例的多个通道

你可以做两件事:

将Second移到IFirst,所以

public interface IFirst
{
    [OperationContract]
    void First();
    [OperationContract]
    void Second();
}

或者为服务实例使用Singleton

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
class Service : IFirst, ISecond
{
...
}

将行为设置为single

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

当您使用InstanceContextMode.PerSession时,这意味着服务为每个client创建a session,因为您试图从两个客户端连接到服务,这就是为什么它创建两个服务实例

通过将其更改为InstanceContextMode.Single,只有一个Service实例将为您的两个客户端提供服务。

从MSDN

System.ServiceModel.InstanceContext 管理关联通道与自定义服务对象之间的连接。使用实例econtextmode枚举ServiceBehaviorAttribute。属性来指定InstanceContext对象的生命周期。可以创建一个新的InstanceContext对象用于每个调用,每个会话或者指定那个InstanceContext对象绑定到单个服务对象。 Single值指定在服务的生命周期内应该使用单个InstanceContext对象。

我知道这篇文章很老了,但对于其他人来说。

你能做的就是把IFirst和issecond合并到ICombinedService中。然后,您将在客户端中创建单个通道——这意味着将创建您的服务主机会话的单个实例。

在您当前的代码中,您正在为IFirst和issecond创建连接[这是您创建的两个会话实例]。)

IFirst iForst = firstFactory.CreateChannel();//创建第一个会话!

isecsecond = secondFactory.CreateChannel();//创建第二个会话!

要改变这种行为,你需要将这些服务组合成一个服务;并且可以在上面进行每个会话的调用。

class Client
{
    static void Main(string[] args)
    {
        ChannelFactory<ICombinedFirstSecond> combinedFactory = new ChannelFactory<ICombinedFirstSecond>(new NetTcpBinding(), new EndpointAddress("net.tcp://localhost:8000"));
        ICombinedFirstSecond iCombinedFirstSecond = combinedFactory.CreateChannel();
        iCombinedFirstSecond.First();
        iCombinedFirstSecond.Second();
        Console.ReadLine();
    }
}
这是我认为你真正需要的,而不是一个单一的服务。