Wie informiert ein WCF-Server einen WCF-Client über Änderungen?(Bessere Lösung als einfaches Abfragen, z. B.Komet oder lange Umfrage)

StackOverflow https://stackoverflow.com/questions/1700917

Frage

siehe auch "WCF drückt über Firewall auf den Kunden"

Ich benötige einen WCF-Client, der eine Verbindung zu einem WCF-Server herstellt und dann einige der Daten verarbeitet Änderungen Auf dem Server müssen die Clients aktualisieren seine Anzeige.

Da zwischen den Clients und dem Server wahrscheinlich eine Firewall vorhanden ist.

  • Die gesamte Kommunikation muss über HTTP erfolgen
  • Der Server kann keinen (physischen) ausgehenden Anruf an den Client tätigen.

Da ich sowohl den Client als auch den Server schreibe, muss ich die Lösung nicht nur auf die Verwendung von Soap usw. beschränken.


Ich suche einen Einbau-Surport für „lange Umfrage" / "Komet" usw


Vielen Dank für die informativste Antwort von Drew Marsh zur Implementierung langer Abfragen in WCF.Ich dachte jedoch, dass das wichtigste „Verkaufsargument“ von WCF darin besteht, dass man so etwas tun kann, indem man einfach die zu verwendenden Kanäle in der Konfigurationsdatei konfiguriert. Ich möchte beispielsweise einen Kanal, der logischerweise in beide Richtungen geht, aber nur physisch eingeht.

War es hilfreich?

Lösung

Für mich hört es sich so an, als wüssten Sie die Antwort bereits:Verwenden Sie lange Abfragen.:) Ich schätze, das Einzige, was noch zu erklären bleibt, ist, wie Sie dies mit WCF und auf die effizienteste Art und Weise erreichen können.


Die Grundlagen:

  1. Entscheiden Sie zunächst, wie lange jede „lange Umfrage“ dauern soll.Aus Gründen der Argumentation werde ich 5-Minuten-Timeouts wählen.
  2. Ändern Sie auf der clientseitigen Bindung die sendTimeout="00:05:00".
  3. Genau wie bei der Verwendung von XmlHttpRequest (XHR) für lange Abfragen müssen Sie, wenn das Timeout tatsächlich auftritt, es erkennen und die nächste Abfrageanforderung erneut ausgeben.Dies ist in WCF recht einfach, da es eine spezielle Ausnahme gibt: TimeoutException, die Sie erkennen können, um leicht zu erkennen, dass dies das Problem war vs.eine andere Ausnahme.
  4. Abhängig davon, wie Sie Ihren WCF-Dienst hosten, müssen Sie sicherstellen, dass er sich selbst so konfiguriert, dass die Verarbeitung bis zu 5 Minuten dauert.Aus reiner WCF-Perspektive sollten Sie sicherstellen, dass Sie Folgendes festlegen receiveTimeout="00:05:00".Wenn Sie jedoch innerhalb von ASP.NET hosten, müssen Sie auch die ASP.NET-Laufzeitumgebung so konfigurieren, dass sie ein höheres Zeitlimit hat, was mithilfe von erfolgt <httpRuntime executionTimeout="300" /> (Notiz: die Maße für dieses Attribut werden in Sekunden angegeben).

Effizient beim Kunden sein

Wenn Sie Ihren Client nur so einrichten, dass er den Dienst synchron aufruft und der Client 5 Minuten lang blockiert, während er auf eine Antwort wartet, ist das keine sehr effiziente Nutzung der Systemressourcen.Sie könnten diese Aufrufe an Hintergrundthreads senden, aber das wird immer noch eine Thread-Ressource belasten, während der Aufruf aussteht.Der effizienteste Weg, damit umzugehen, ist die Verwendung asynchroner Vorgänge.

Wenn Sie Ihre Serviceverträge manuell erstellen, empfehle ich Ihnen, einen Blick darauf zu werfen diesen Abschnitt auf MSDN weiter OperationContractAttribute.AsyncPattern Einzelheiten zum Hinzufügen eines BeginXXX/EndXXX asynchrones Methodenpaar für jeden Ihrer Aufrufe.Wenn Sie jedoch verwenden svcutil Um Ihre Betriebsverträge für Sie zu generieren, müssen Sie lediglich die übergeben, damit asynchrone Methoden generiert werden /async Option in der Befehlszeile.Weitere Einzelheiten zu diesem Thema finden Sie unter Schauen Sie sich das Thema „Synchronous and Asynchronous“ auf MSDN an.

Nachdem Sie nun Ihre asynchronen Vorgänge definiert haben, ähnelt das Muster stark der Arbeit mit XHR.Du rufst an BeginXXX Methode, an die Sie übergeben ein AsyncCallback delegieren.Der BeginXXX Die Methode gibt Ihnen eine zurück IAsyncResult, an dem Sie entweder festhalten können, wenn Sie auf den Vorgang warten möchten (in fortgeschritteneren Szenarien), oder ihn ignorieren können. Anschließend sendet die WCF-Infrastruktur die Anforderung asynchron an den Server und wartet hinter den Kulissen auf eine Antwort.Wenn eine Antwort eingeht oder eine Ausnahme auftritt, der Rückruf, den Sie an übergeben haben BeginXXX Methode wird aufgerufen.Innerhalb dieser Rückrufmethode müssen Sie die entsprechende aufrufen EndXXX Methode, die die übergibt IAsyncResult das wird dir übergeben.Während des Anrufs beim EndXXX -Methode müssen Sie eine Ausnahmebehandlung einsetzen, um jede Art von logischem Fehler zu behandeln, der möglicherweise beim Aufrufen der Methode aufgetreten ist. Dies ist jedoch auch der Punkt, an dem Sie den Fehler jetzt abfangen können TimeoutException wir haben vorhin darüber gesprochen.Vorausgesetzt, Sie haben eine gute Antwort erhalten, werden die Daten vom zurückgegeben EndXXX Rufen Sie an und Sie können auf diese Daten auf jede sinnvolle Weise reagieren.

NOTIZ: Eine Sache, die Sie bei diesem Muster beachten sollten, ist die Art des Einfädelns.Die asynchronen Rückrufe von WCF werden in einem Thread von empfangen Der verwaltete Thread-Pool.Wenn Sie planen, die Benutzeroberfläche in einer Technologie wie WPF oder WinForms zu aktualisieren, müssen Sie sicherstellen, dass Sie die Aufrufe mithilfe von an den UI-Thread zurückmarshallen Invoke oder BeginInvoke Methoden.

Effizient auf dem Server sein

Wenn wir uns Sorgen um die Effizienz des Clients machen, sollten wir uns das doppelte Sorgen machen, wenn es um den Server geht.Offensichtlich stellt diese Art von Ansatz höhere Anforderungen an die Serverseite, da eine Verbindung offen und ausstehend bleiben muss, bis es einen Grund gibt, eine Benachrichtigung an den Client zurückzusenden.Die Herausforderung hierbei besteht darin, dass Sie die WCF-Laufzeit nur mit der Verarbeitung derjenigen Clients verknüpfen möchten, denen tatsächlich ein Ereignis gesendet wird.Alles andere sollte einfach schlafen und darauf warten, dass das Ereignis eintritt.Glücklicherweise funktioniert das gleiche asynchrone Muster, das wir gerade auf der Clientseite verwendet haben, auch auf der Serverseite.Allerdings gibt es mittlerweile einen großen Unterschied:Jetzt Du muss die zurückgeben IAsyncResult (und damit ein WaitHandle) von dem BeginXXX Methode, die die WCF-Laufzeit dann auf das Signal wartet, bevor sie Ihre aufruft EndXXX Methode.

Du wirst nicht Abgesehen von den Links, die ich bereits zuvor bereitgestellt habe, finden sich in MSDN viele weitere Dokumentationen, und leider sind die Beispiele zum Schreiben eines Async-Dienstes nicht sehr nützlich.Das gesagt, Wenlong Dong hat einen Artikel über die Skalierung von WCF-Diensten mit dem asynchronen Modell geschrieben vor einiger Zeit, das ich Ihnen wärmstens empfehlen kann.

Darüber hinaus kann ich ehrlich gesagt nicht viele Ratschläge dazu geben, wie Sie das asynchrone Modell auf der Serverseite am besten für Sie implementieren können, da es völlig davon abhängt, aus welcher Art von Datenquelle Ihre Ereignisse überhaupt stammen.Datei-E/A?Eine Nachrichtenwarteschlange?Eine Datenbank?Gibt es eine andere proprietäre Software mit eigenem Messaging-Dienst, die Sie mit einer Fassade versehen möchten?Ich weiß es nicht, aber sie sollten alle eigene asynchrone Modelle anbieten, auf die Sie Ihren eigenen Dienst zurückgreifen können, um ihn so effizient wie möglich zu gestalten.

Aktualisiertes Rezept

Da dies eine beliebte Antwort zu sein scheint, dachte ich, ich sollte angesichts der jüngsten Veränderungen in der Landschaft hierher zurückkommen und ein Update bereitstellen.An dieser Stelle gibt es nun eine .NET-Bibliothek namens SignalR das genau diese Funktionalität bietet und ich würde auf jeden Fall empfehlen, eine solche Kommunikation mit dem Server zu implementieren.

Andere Tipps

Wenn der Server eine ausgehende Verbindung zu einem Service-Bus machen konnte könnten Sie eine Art von Anruf implament zurück. Auf diese Weise der Client / Server nicht brauchen überhaupt umeinander zu wissen, nur die Berufung Service Bus. Siehe .NET Service Bus

Sie suchen möchten in WSDualHttpBinding

  

Das WSDualHttpBinding stellt den   gleiche Unterstützung für Web-Service-Protokolle   als WSHttpBinding, aber für den Einsatz mit   Duplex-Verträge. WSDualHttpBinding   nur unterstützt SOAP Sicherheit und   erfordert zuverlässiges Messaging. Diese   Bindung erfordert, dass der Client eine   öffentliche URI, die einen Rückruf bietet   Endpunkt für den Dienst. Das ist   durch die ClientBaseAddress vorgesehen. EIN   Dual-Bindung macht die IP-Adresse   der Client an den Dienst. Der Kunde   Sicherheit verwenden soll, dass es, um sicherzustellen,   nur eine Verbindung zu Diensten er vertraut.   

Während Sie nicht WCF könnten versuchen, XMPP zu verwenden, die Funktionalität zu erhalten gehen. Es gibt einen Artikel über InfoQ über sie und andere Systeme. Während der Artikel heißt es, dass XMPP nicht über HTTP verwendet werden kann, können Sie bei der Verwendung von BOSH .

Es gibt .NET-Bibliotheken verfügbar agsXMPP einen nennen.

Das Unternehmen, in dem ich arbeiten beginnt, es zu benutzen Update-Benachrichtigungen an eine Anwendung zu drängen es Teile der Benutzeroberfläche zu aktualisieren.

Google für „ WCF-Duplex “. Ich habe diese erfolgreich mit netTcpBinding (über Kontinente) verwendet, aber ich bin mir nicht sicher über Basichttpbinding.

Allerdings hat es den Server erfordern zurück an den Client zu nennen. Wenn der Server nicht erlaubt, dies zu tun, Polling Ihre einzige Option sein kann ...

Wenn der Server den Client nicht nennen (und es sollte nicht in der Regel) sollten Sie die Client-Abfrage haben den Server als Sie angegeben haben. da Sie WCF Fundament haben bereits vorhanden, fügen Sie einfach eine Operation für das.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top