Соединение TCP Keep Alive, размещенное в WCF - PullRequest
1 голос
/ 27 марта 2012

Я пытаюсь разместить клиентское соединение TCP в службе wcf, которая связывается с приложением стороннего производителя.Служба 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();
    }
}

1 Ответ

3 голосов
/ 28 марта 2012

Когда вы должны установить / разорвать ваше TCP-соединение, зависит от того, когда и сколько ваших служебных объектов (MessageProcessor) было создано / удалено.

WCF очень гибок и работает со многими различными моделями. Они контролируются InstanceContextMode и ConcurrencyMode вашего сервиса. Они могут быть установлены в вашем конфигурационном файле или в коде при создании службы.

InstanceContextMode определяет, когда создается ваш сервисный объект. Есть три варианта.

1) За звонок . Каждый раз, когда клиент вызывает один из ваших методов обслуживания, будет создан новый экземпляр вашего MessageProcessor. Даже если один и тот же клиент вызывает два метода, вы получите два объекта MessageProcessor. Это значение по умолчанию.

2) За сеанс : Некоторые транспорты (например, TCP) поддерживают надежные сеансы. Клиент подключается, чтобы начать новые сеансы, и будет создан экземпляр вашего объекта MessageProcessor. Клиент может вызвать много методов, и тот же экземпляр будет обрабатывать их. Когда клиент отключается, объект будет уничтожен. Обратите внимание, что многие клиенты будут по-прежнему создавать множество объектов MessageProcessor (каждый клиент имеет свой собственный сеанс).

3) Single : Все сервисные вызовы используют один и тот же экземпляр вашего объекта MessageProcessor. Объект живет до тех пор, пока хост службы жив.

ConcurrencyMode контролирует количество потоков, разрешенных для одного и того же объекта службы. Например, с помощью Single instanceContext вы можете разрешить одновременное обслуживание нескольких клиентских вызовов в разных потоках, или вы можете заставить WCF разрешать только один поток за раз в ваш MessageProcessor, если он не является потокобезопасным.

Учитывая, что вы хотите поддерживать свое TCP-соединение в течение всего времени, необходимого клиентам, это зависит от того, какой InstanceContextMode вы используете, где и как вы подключаете / отключаете ваше TCP-соединение. Например, если вы используете одиночный режим, вы просто подключитесь во время создания хоста службы и отключитесь, когда хост выключится. При использовании режима Per Call вы можете отключиться, когда все сервисные объекты будут уничтожены, или подождать некоторое время, если поступит другой вызов. Это действительно ваше дело.

...