2009-05-22 5 views
14

Ich bin komplett neu in WCF. Ich war mir ziemlich sicher, dass es wie normale Webdienste funktionieren würde - und ich bin mir auch ziemlich sicher, dass ich das auch falsch gemacht habe, aber jetzt möchte ich sicherstellen, dass ich es richtig mache.Verwenden von WCF in einer ASP.Net-Anwendung und Best Practices

Unsere ASP.Net App verbindet sich mit dem WCF-Dienst über das Internet. Ich habe grundlegende Sicherheit implementiert und SSL verwendet. Es funktioniert, aber langsamer als bei regulären Webdiensten. Die zurückgegebenen Daten entsprechen im Wesentlichen denen des regulären Webdienstes.

Wenn ich den regulären Webdienst nutzte, musste ich jedes Mal, wenn ich Daten abrufen musste, ein neues Serviceobjekt erstellen und die Funktion für die benötigten Daten aufrufen. Das schien in Ordnung zu sein, aber wie ich mir vorstellen konnte, war es nicht der beste Weg, es zu tun, besonders wenn Tausende von Benutzern gleichzeitig verbunden waren. Als ich zu WCF konvertiert habe, habe ich beschlossen, einen Client offen zu halten und ihn nur für alle zu verwenden, die sich mit der Site verbinden. Ich habe es in den Cache gestellt, und wenn der Cache das Objekt auswerfen würde, hatte ich eine Rückruffunktion, um es zu entfernen.

Jetzt habe ich nicht einmal darüber nachgedacht, bis ich all das geändert habe, dass es ein Problem für mehrere Leute darstellen könnte. Wenn Person A Daten anfordert, muss Person B darauf warten, dass dies beendet ist, bevor ihre Daten über den Dienst abgerufen werden.

Also änderte ich es auf Session-basierte. Ich habe das entweder falsch umgesetzt oder es ist einfach fehlgeschlagen, da es überhaupt nicht gut funktioniert hat. Der Client würde eine Zeitüberschreitung verursachen, einen Fehler verursachen oder einfach nicht arbeiten. Ich habe es für den Moment zurück auf Cache geändert und es scheint gut zu funktionieren (außer langsam).

Was ist eine "Best Practice" für dieses Szenario? Erstelle ich den Client im laufenden Betrieb, wenn er benötigt wird, erstelle ich eine Sitzung (und finde heraus, was ich falsch gemacht habe), oder behalte ich ihn so wie er ist und verwende die zwischengespeicherte Client-Methode?

+0

+1. Gute Frage. – AnthonyWJones

Antwort

6

Diese Art von Problem wird normalerweise durch die Pflege eines Pools gelöst. Statt nur ein Dienstobjekt in einem Extrem und einen pro Benutzer im anderen Extrem zu haben, würde der Pool eine Sammlung von Dienstobjekten enthalten, die benötigt werden, um den aktuellen Bedarf für ihre Dienste zu unterstützen. Daher sollte der Pool nur bis zu einem Punkt maximaler Nachfrage wachsen.

Sie würden sicherstellen, dass Objekte vor einem anderen Timeout innerhalb des Serviceobjekts aus dem Pool herausfallen und auch sicherstellen, dass sie aus dem Pool fallen, wenn sie irgendeine Ausnahme haben.

Auf diese Weise haben Sie nicht mehrere Clientanforderungen, die auf den Zugriff auf ein einzelnes Objekt warten, noch leere Objekte in einem Dienst herumhängen und wahrscheinlich im hohen Alter sterben, bevor sie wieder verwendet werden können.

+1

Nie gedacht, einen Pool von Clients zu erstellen. Dies könnte das Beste aus beiden Welten sein. Nicht eine Tonne von Objekten im laufenden Betrieb erstellen und auch nicht verlangsamen, wenn es viel Aktivität gibt. Großartige Idee! – TheCodeMonk

+0

Ich mag die erwähnte Technik, jede Art und Weise, wie Sie auf eine Implementierung davon hinweisen könnten, damit ich herumspielen kann? –

+0

So beängstigend das klingen mag, ich habe bereits eine gute Umsetzung dazu. Ich werde es testen und wenn es so funktioniert, wie ich es erwarte, werde ich einen Blogbeitrag darüber schreiben und dokumentieren, was ich getan habe. – TheCodeMonk

1

Normalerweise erstelle ich einen Client im laufenden Betrieb, wie Sie bereits erwähnt haben, aber stellen Sie sicher, dass Sie darüber verfügen, nachdem die Anfrage abgeschlossen ist. Ich habe dies ohne große Probleme gemacht, aber um ehrlich zu sein, habe ich nicht mehr als 1000 Benutzer, die genau denselben Service zur gleichen Zeit nutzen.

Sie können die genauen Implementierungsdetails in this Blogpost finden, wenn Sie interessiert sind.

Nur um etwas zu verdeutlichen, das Sie in der Frage erwähnt haben - wenn Sie sagen "regulären Web-Service", sprechen Sie über ASMX oder?

+0

Ja, ASMX. Die Entsorgung war die Sache, um die ich mir am meisten Sorgen machte. Ich denke, ich muss etwas Refactoring machen, um das Ganze zu reinigen. – TheCodeMonk

4

Die allgemeine beste Praxis für WCF-Dienste wäre es, wenn immer möglich, das Einzelanmeldungsmodell pro Aufruf zu verwenden. Dies gibt Ihnen den besten Durchsatz, das beste und einfachste Verhalten in der Serviceinstanz. Wenn möglich, und wenn Sie keinen zwingenden Grund haben, verwenden Sie dieses Modell.

Es scheint, dass in Ihrem Fall das Erstellen der Dienstinstanz eine ziemlich teure Operation ist. Vielleicht müssen Sie dies irgendwie bereinigen - machen Sie die tatsächliche Service-Instanz sehr schlank und leicht, so dass sie in einem Augenblick (oder weniger) erstellt und entsorgt werden kann und dann einige Hintergrund-Arbeitsprozesse (oder möglicherweise einen Pool) hat von denen, wie von Anthony vorgeschlagen), die Sie dann von Ihren tatsächlichen Service-Instanzen aufrufen können.

Marc