2012-03-27 6 views
1

Ich versuche, eine TCP-Clientverbindung in einem WCF-Dienst zu hosten, der mit einer Drittanbieter-App kommuniziert. Der WCF-Dienst wickelt die TCP-Aufrufe an die Drittanbieteranwendung um, sodass jede Anwendung, die eine Verbindung mit dem WCF-Dienst herstellt, keine Kenntnis von der TCP-Verbindung hat. Aufgrund des Protokolls, das die Drittanbieter-App benötigt, muss die TCP-Verbindung am Leben erhalten werden. Ich habe die Logik implementiert, um Fehler zu behandeln und die Verbindung wiederherzustellen, aber das Problem, mit dem ich konfrontiert bin, ist, wie ich diese Verbindung öffne und schließe. Gibt es eine Möglichkeit für mich, die offenen und schließenden Anrufe des Hosts zu überschreiben, so dass ich dasselbe mit meinem CommunicationService machen kann?TCP Keep Alive-Verbindung gehostet in WCF

Mein Code:

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

Was erwarten Sie, wenn zwei Clients (und damit zwei Threads) gleichzeitig versuchen, Ihre 'ProcessMessage'-Methode (und im Prinzip auch Ihre TCP-Verbindung) aufzurufen? –

+0

Welchen InstanceContextMode verwenden Sie für Ihren Service? Dies wird die Lebensdauer und mögliche mehrere Instanzen von MessageProcessor stark bestimmen. – GazTheDestroyer

+0

KirkWoll, ich habe Logik innerhalb meiner Kommunikationsklasse, um Multithreading zu handhaben.Ich stehe Nachrichten an und gebe ihnen Priorität basierend auf ihrem Typ. GazTheDestroyer, ich fürchte, ich bin mir nicht sicher, was Sie meinen, das ist das erste Mal, dass ich mit WCF gearbeitet habe. Was mache ich nicht ideal? Gibt es einen besseren Weg, dies zu tun? – jtiger

Antwort

2

Wann sollten Sie setup/abreißen Verbindung TCP hängt davon ab, wann und wie viele Ihr Dienstobjekt (Message) erstellt/angeordnet.

WCF ist sehr flexibel und verarbeitet viele verschiedene Modelle. Diese werden vom InstanceContextMode und dem ConcurrencyMode Ihres Dienstes gesteuert. Diese können in Ihrer Konfigurationsdatei oder in Code festgelegt werden, wenn der Dienst erstellt wird.

InstanceContextMode steuert, wenn Ihr Serviceobjekt erstellt wird. Es gibt drei Möglichkeiten.

1) Pro Anruf. Jedes Mal, wenn ein Client eine Ihrer Servicemethoden aufruft, wird eine neue Instanz Ihres MessageProcessors erstellt. Selbst wenn derselbe Client zwei Methoden aufruft, erhalten Sie zwei MessageProcessor-Objekte. Dies ist der Standardwert.

2) Pro Sitzung: Einige Transporte (z. B. TCP) unterstützen zuverlässige Sitzungen. Der Client stellt eine Verbindung her, die eine neue Sitzung startet, und eine Instanz Ihres MessageProcessor-Objekts wird erstellt. Der Client kann viele Methoden aufrufen, und dieselbe Instanz verarbeitet sie. Wenn der Client die Verbindung trennt, wird das Objekt zerstört. Beachten Sie, dass viele Clients immer noch zu vielen MessageProcessor-Objekten führen (jeder Client hat seine eigene Sitzung).

3) Einzeln: Alle Serviceaufrufe verwenden dieselbe Instanz Ihres MessageProcessor-Objekts. Das Objekt lebt so lange, wie der Service-Host lebt.

Der ConcurrencyMode steuert, wie viele Threads in dasselbe Serviceobjekt zulässig sind. Mit einem einzelnen instanceContext können Sie beispielsweise mehrere Clientaufrufe gleichzeitig auf verschiedenen Threads warten lassen oder WCF zwingen, jeweils nur einen Thread in Ihren MessageProcessor zuzulassen, wenn er nicht threadsicher ist.

Vorausgesetzt, dass Sie Ihre TCP-Verbindung live halten wollen, so lange Clients sie benötigen, hängt es davon ab, welchen InstanceContextMode Sie verwenden, wo und wie Sie Ihre TCP-Verbindung herstellen/trennen. Wenn Sie beispielsweise den Single-Modus verwenden, würden Sie beim Erstellen des Service-Hosts einfach eine Verbindung herstellen und die Verbindung trennen, wenn der Host heruntergefahren wird. Wenn Sie den Modus "Pro Anruf" verwenden, werden Sie möglicherweise die Verbindung trennen, wenn alle Dienstobjekte zerstört wurden, oder Sie warten vielleicht kurz, bis ein weiterer Anruf eingeht. Es liegt ganz bei Ihnen.

+0

Danke für die Erklärung. Ich verwende Single for InstanceContextMode und erlaube WCF nur, jeweils einen einzelnen Anruf zu bedienen. Scheint so weit zu arbeiten! – jtiger

Verwandte Themen