我正在尝试在与第三方应用程序通信的wcf服务中托管TCP客户端连接。 WCF服务将tcp调用包装到第三方应用程序,以便连接到WCF服务的任何应用程序都不知道TCP连接。由于第三方应用程序所需的协议,tcp连接必须保持活动状态。我已经实现了处理错误和重新连接的逻辑,但我遇到的问题是如何打开和关闭此连接。有没有办法覆盖主机的Open和Close调用,以便我可以对我的CommunicationService执行相同的操作?
我的代码:
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 :(得分:2)
设置/拆除TCP连接时,取决于创建/处理服务对象(MessageProcessor)的时间和数量。
WCF非常灵活,可以处理许多不同的模型。它们由您的服务的InstanceContextMode和ConcurrencyMode控制。这些可以在配置文件中设置,也可以在创建服务时在代码中设置。
InstanceContextMode 控制何时创建服务对象。有三种选择。
1)每次通话。每次客户端调用您的一个服务方法时,都会创建一个MessageProcessor的新实例。即使它是同一个客户端调用两个方法,您将获得两个MessageProcessor对象。这是默认值。
2)每个会话:某些传输(例如TCP)支持可靠的会话。客户端连接将启动新会话,并将创建MessageProcessor对象的实例。客户端可以调用许多方法,同一个实例将处理它们。当客户端断开连接时,对象将被销毁。请注意,许多客户端仍将生成许多MessageProcessor对象(每个客户端都有自己的会话)。
3)单个:所有服务调用都使用MessageProcessor对象的相同实例。只要服务主机处于活动状态,该对象就会存在。
ConcurrencyMode 控制允许多少线程进入同一服务对象。例如,使用Single instanceContext,您可能允许在不同的线程上同时为多个客户端调用提供服务,或者您可能希望强制WCF一次只允许一个线程进入MessageProcessor,如果它不是线程安全的。
鉴于您希望在客户端需要时保持TCP连接,它取决于您使用的InstanceContextMode,以及您连接/断开TCP连接的位置和方式。例如,如果使用单一模式,则只需在创建服务主机时进行连接,并在主机关闭时断开连接。如果使用“每次呼叫”模式,您可能会在所有服务对象被销毁时断开连接,或者等待一段时间以防其他呼叫进入。这完全取决于您。