2012-03-27 48 views
1

我正在尝试在与第三方应用程序通信的wcf服务中托管TCP客户端连接。 WCF服务将tcp调用包装到第三方应用程序,以便连接到WCF服务的任何应用程序都不知道TCP连接。由于第三方应用程序需要的协议,tcp连接必须保持活动状态。我已经实现了处理错误和重新连接的逻辑,但是我遇到的问题是如何打开和关闭此连接。有没有办法让我重写主机打开和关闭的呼叫,以便我可以对我的CommunicationService做同样的事情?TCP Keep Alive连接托管在WCF中

我的代码:

public partial class HostService : ServiceBase 
{ 
    private ServiceHost _host; 

    public HostService() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnStart(string[] args) 
    { 
     Type serviceType = typeof(MessageProcessor); 
     var serviceUri = new Uri("http://localhost:9091/"); 
     _host = new ServiceHost(serviceType, serviceUri); 
     _host.Open(); 
    } 

    protected override void OnStop() 
    { 
     _host.Close(); 
    } 
} 

[ServiceContract] 
public interface IMessageProcessor 
{ 
    [OperationContract] 
    void ProcessMessage(string message); 
} 

public class MessageProcessor : IMessageProcessor 
{ 
    //This is handling my TCP connection. 
    private CommunicationService _communicationService; 

    public MessageProcessor() 
    { 
     _communicationService = new CommunicationService(); 
    } 

    public void ProcessMessage(string message) 
    { 
     if(_communicationService.Connected) 
     { 
      var request = new QueryMessage(); 
      var result = _communicationService.TransmitMessage(request); 
     } 
     else 
     { 
      //Error handling, not necessary for now 
     } 
    } 
    //I want to do this 
    public override Open() 
    { 
     _communicationService.Open(); 
    } 
    public override Close() 
    { 
     _communicationService.Close(); 
    } 
} 
+0

当两个客户端(因此两个线程)试图同时调用您的ProcessMessage方法(原则上是您的TCP连接)时,您会发生什么? – 2012-03-27 14:42:12

+0

你使用什么InstanceContextMode来为你的服务?这将大大决定MessageProcessor的生命周期和潜在多个实例。 – GazTheDestroyer 2012-03-27 15:06:01

+0

KirkWoll,我的通信类中有逻辑来处理多线程。我排队消息并根据其类型给予优先级。 GazTheDestroyer,恐怕我不确定你指的是什么,这是我第一次使用WCF。我在做什么不理想?有一个更好的方法吗? – jtiger 2012-03-27 17:13:18

回答

2

时候你应该安装/拆掉你的TCP连接取决于在创建/配置时,有多少你的服务对象(MessageProcessor的)对。

WCF非常灵活,可以处理许多不同的模型。这些由您的服务的InstanceContextMode和ConcurrencyMode控制。这些可以在您的配置文件中或在创建服务时在代码中设置。

InstanceContextMode控制何时创建服务对象。有三种选择。

1)每个呼叫。客户端每次调用其中一个服务方法时,都会创建一个新的MessageProcessor实例。即使调用两个方法的客户端相同,您也会得到两个MessageProcessor对象。这是默认设置。

2)每个会话:一些传输(如TCP)支持可靠的会话。客户端连接将启动一个新的会话,并创建一个MessageProcessor对象的实例。客户端可以调用多种方法,同一个实例将处理它们。当客户端断开时,对象将被销毁。请注意,许多客户端仍然会导致许多MessageProcessor对象(每个客户端都有自己的会话)。

3)单个:所有服务调用都使用MessageProcessor对象的相同实例。只要服务主机还活着,对象就会一直存在。

并发模式控制允许多少个线程进入同一服务对象。例如,使用Single instanceContext,您可能允许在不同线程上同时处理多个客户端调用,或者,如果线程不安全,您可能希望强制WCF一次只允许一个线程进入MessageProcessor。

由于您希望只要客户端需要TCP连接,它取决于您使用的InstanceContextMode在何处以及如何连接/断开TCP连接。例如,如果使用Single模式,则只需在创建服务主机时进行连接,并在主机关闭时断开连接。如果使用Per Call模式,当所有服务对象被销毁时,您可能会断开连接,或者等待很短的时间以防其他呼叫进入。这真的取决于您。

+0

感谢您的解释。我使用Single作为InstanceContextMode,并且只允许WCF一次处理单个呼叫。似乎到目前为止工作! – jtiger 2012-03-28 14:32:57