问题
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