WCF Multiple channels for one service instance

北战南征 提交于 2019-12-24 05:37:25

问题


This is my code for server application:

[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();
    }
}

and client:

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();

    }
}

When I run it I get output:

Successfully opened port 8000.
Service 1 created.
First function. ServiceID: 1
Service 2 created.
Second function. ServiceID: 2

In my case server creates two instances of Service. What I want to do is call Second function for the same Service instance that First did.


回答1:


You can do two things:

Move Second to IFirst so

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

    [OperationContract]
    void Second();
}

Or use a Singleton for the service instance

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



回答2:


Change your behaviour to single

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

As you are using InstanceContextMode.PerSession that means service creates a session for each client as You are trying to connect to service from two clients thats why it is creating two instances of Service

by changing it to InstanceContextMode.Single only one instance of Service will serve both of your clients.

From MSDN

The System.ServiceModel.InstanceContext manages the association between the channel and the user-defined service objects. Use the InstanceContextMode enumeration with the ServiceBehaviorAttribute.InstanceContextMode property to specify the lifetime of the InstanceContext object. can create a new InstanceContext object for every call, every session or specify that the InstanceContext object is bound to a single service object. The Single value specifies that a single InstanceContext object should be used for the lifetime of the service.




回答3:


I know the post is old, but for others.

What you can do is combine your IFirst and ISecond into ICombinedService. Then you would create a single channel in your client - meaning a single instance of your service host session would be created.

In your current code you are creating a connection for IFirst, and ISecond [These are the two session instances you created.]

IFirst iForst = firstFactory.CreateChannel(); // First Session Created!

ISecond iSecond = secondFactory.CreateChannel(); // Second Session Created!

To change that behavior you will need to combine the services into one service; and can make per session calls on that.

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();

    }
}

This is what I think you really are looking for and not a singleton service.



来源:https://stackoverflow.com/questions/8504059/wcf-multiple-channels-for-one-service-instance

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!