W jaki sposób serwer WCF informuje klienta WCF o zmianach? (Lepsze rozwiązanie niż proste sondowanie, np. Kometa lub długie sondowanie)

Zobacz też " WCF push to client through firewall "

Muszę mieć klienta WCF, który łączy się z serwerem WCF, a następnie gdy niektóre dane zmienią się na serwerze, klienci muszązaktualizować jego wyświetlanie.

Ponieważ prawdopodobnie istnieje firewall między klientami a serwerem.

  • wszystkie komunikaty muszą być przez HTTP
  • serwer nie może wykonać (fizycznego) połączenia wychodzącego do klient.

ponieważ piszę zarówno Klienta jak i serwer nie muszę ograniczać rozwiązania tylko do używania soap itp.


Szukam wbudowanego surportu dla " long ankiet" / "Kometa " itd


Dzięki za najbardziej pouczającą odpowiedź od Drew Marsh na temat tego, jak wdrożyć długie ankiety w WCF. Jednak myślałem, że głównym "punktem sprzedaży" WCF było to, że można zrobić tego rodzaju rzeczy po prostu konfigurując kanały do być używane w pliku konfiguracyjnym. E. g chcę kanał, który logicznie dwukierunkowy, ale tylko fizycznie przychodzące.

Author: Community, 2009-11-09

5 answers

Wydaje mi się, że znasz już odpowiedź: użyj długich sondaży. :) Więc chyba jedyne, co pozostało do wyjaśnienia, to jak możesz być w stanie to osiągnąć z WCF i w najbardziej efektywny możliwy sposób.


Podstawy:

  1. najpierw zdecyduj, jak długo ma być każda "długa ankieta". Na marginesie wybieram 5min timeouts.
  2. Po stronie klienta, Zmień sendTimeout="00:05:00".
  3. podobnie jak używanie XmlHttpRequest (XHR) przez długi czas ankieta, gdy timeout rzeczywiście występuje, będziesz musiał go wykryć i ponownie wydać następne żądanie ankiety. Jest to dość łatwe w WCF, ponieważ istnieje szczególny wyjątek, TimeoutException, że można złapać, aby łatwo wykryć, że to był problem vs. jakiś inny wyjątek.
  4. w zależności od tego, w jaki sposób hostujesz usługę WCF, musisz upewnić się, że skonfigurujesz się tak, aby umożliwić przetwarzanie przez maksymalnie 5 minut. Z czystej perspektywy WCF będziesz chciał się upewnić, że ustawiłeś receiveTimeout="00:05:00". Jednak, jeśli jesteś gospodarzem wewnątrz ASP.NET będziesz również musiał skonfigurować ASP.NET runtime, aby mieć wyższy limit czasu, który odbywa się za pomocą <httpRuntime executionTimeout="300" /> (Uwaga: pomiary są w sekundach dla tego atrybutu).
Jest skuteczny w kliencie]}

Jeśli skonfigurujesz klienta tak, aby synchronicznie wywoływał usługę, a Klient blokuje się przez 5 minut czekając na odpowiedź, nie jest to zbyt efektywne wykorzystanie zasobów systemowych. Możesz włączyć te telefony wątki w tle, ale to nadal będzie przeżuwać zasób wątku, podczas gdy połączenie jest wybitne. Najskuteczniejszym sposobem radzenia sobie z tym jest użycie operacji asynchronicznych.

Jeśli tworzysz umowy serwisowe ręcznie, sugerowałbym sprawdzenie tej sekcji na MSDN na OperationContractAttribute.AsyncPattern szczegółowe informacje jak dodać BeginXXX/EndXXX para metod asynchronicznych dla każdego z Twoich połączeń. Jeśli jednak używasz svcutil do generowania kontraktów operacyjnych, wszystko, co musisz zrobić, aby mieć metody asynchroniczne generowane są za pomocą opcji /async w wierszu poleceń. Aby uzyskać więcej informacji na ten temat, sprawdź temat synchroniczny i asynchroniczny na MSDN.

Teraz, gdy masz już zdefiniowane operacje asynchroniczne, wzór jest bardzo podobny do pracy z XHR. Metodę BeginXXX, do której przekazujesz nazywamy AsyncCallback delegatem . Metoda BeginXXX zwróci ci IAsyncResult, które możesz albo zatrzymać, jeśli chcesz móc czekać na operację (w bardziej zaawansowane scenariusze) lub zignorować, a następnie Infrastruktura WCF asynchronicznie wyśle żądanie do serwera i czeka na odpowiedź za kulisami. Gdy odpowiedź zostanie odebrana lub wystąpi wyjątek, wywołane zostanie wywołanie zwrotne przekazane do metody BeginXXX. Wewnątrz tej metody callback musisz wywołać odpowiednią metodę EndXXX przechodzącą w IAsyncResult, która jest przekazywana do ciebie. Podczas wywołania metody EndXXX musisz użyć obsługi wyjątków, aby obsłużyć z każdym rodzajem błędu logicznego, który mógł wystąpić podczas wywoływania metody, ale to również miejsce, w którym możesz teraz złapać TimeoutException, o którym rozmawialiśmy wcześniej. Zakładając, że otrzymałeś dobrą odpowiedź, dane będą zwracane z wywołania EndXXX i możesz reagować na te dane w dowolny sposób.

Uwaga: jedną z rzeczy, o których należy pamiętać w tym wzorze, jest natura wątku. W związku z tym, że WCF nie jest w stanie zapewnić dostępu do danych, nie jest w stanie uzyskać dostępu do tych danych. Pula wątków . Jeśli planujesz aktualizację interfejsu użytkownika w technologii takiej jak WPF lub WinForms, musisz upewnić się, że wywołania powracają do wątku UI za pomocą Invoke lub BeginInvoke metody.

Bycie wydajnym na serwerze

Jeśli mamy martwić się o wydajność w kliencie, powinniśmy być podwójnie tacy, jeśli chodzi o serwer. Oczywiście tego typu podejście stawia większe zapotrzebowanie po stronie serwera, ponieważ połączenie musi pozostać otwarte i Oczekujące, dopóki nie ma powodu, aby wysłać powiadomienie z powrotem do klienta. Wyzwanie polega na tym, że chcesz powiązać środowisko uruchomieniowe WCF z przetwarzaniem tych klientów, którzy faktycznie są wysyłani. Wszystko inne powinno po prostu spać, czekając na wydarzenie. Na szczęście ten sam wzorzec asynchroniczny, którego właśnie użyliśmy po stronie klienta, działa również po stronie serwerów. Jednak jest teraz duża różnica: teraz ty musisz zwrócić IAsyncResult (a więc WaitHandle) Z metody BeginXXX, którą Runtime WCF będzie czekać na sygnalizację przed wywołaniem metody EndXXX.

Będziesz Nie znaleźć wiele w sposób dokumentacji wewnątrz MSDN inne niż linki, które już podałem wcześniej i, niestety, ich próbki przy pisaniu usługi asynchronicznej są mniej niż przydatne. To powiedziawszy, Wenlong Dong napisał jakiś czas temu artykuł o skalowaniu usług WCF za pomocą modelu async. Zobacz też

Poza tym, szczerze mówiąc, nie mogę dać zbyt wiele rad, jak najlepiej zaimplementować model asynchroniczny po stronie serwera dla Ciebie, ponieważ zależy to całkowicie od tego, z jakiego źródła danych będą pochodzić twoje wydarzenia. Plik I / O? Kolejka komunikatów? Baza danych? Jakieś inne oprogramowanie własnościowe z własnym komunikatorem, które starasz się zapewnić? Nie wiem, ale wszystkie powinny oferować własne modele asynchroniczne, na których można wróć do własnej usługi, aby była jak najbardziej wydajna.

Zaktualizowana Recepta

Ponieważ wydaje się to być popularna odpowiedź, pomyślałem, że powinienem wrócić tutaj i dostarczyć aktualizację biorąc pod uwagę ostatnie zmiany w krajobrazie. W tym momencie istnieje teraz biblioteka. NET o nazwie SignalR , która zapewnia tę dokładną funkcjonalność i jest zdecydowanie tak, jak polecam implementację takiej komunikacji z serwerem.

 48
Author: Drew Marsh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-12 21:46:15

Podczas gdy nie WCF możesz spróbować użyć XMPP, aby uruchomić tę funkcjonalność. Jest artykuł o InfoQ{[2] } o it i innych systemach. Podczas gdy artykuł stwierdza, że XMPP nie może być używany przez HTTP, możesz użyć BOSH .

Istnieją biblioteki.NET dostępne agsXMPP aby wymienić jedną.

Firma, w której pracuję, zaczyna używać go do wysyłania powiadomień o aktualizacji do aplikacji, aby odświeżyć części interfejsu użytkownika.

 2
Author: BennyM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-12 13:12:25

Google dla "WCF duplex ". Korzystałem z tego z powodzeniem używając netTcpBinding( na różnych kontynentach), ale nie jestem pewien co do basicHttpBinding.

Wymaga jednak, aby serwer oddzwaniał do klienta. Jeśli serwer nie może tego zrobić, sondowanie może być jedyną opcją...

 1
Author: Vijay Patel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-09 13:36:27

Jeśli serwer mógłby nawiązać połączenie wychodzące z magistralą usługową, można by wywołać rodzaj połączenia zwrotnego. W ten sposób klient / serwer nie musiałby w ogóle wiedzieć o sobie nawzajem, tylko o magistrali usług. Zobacz . Net Service Bus

będziesz chciał zajrzeć do WSDualHttpBinding

WSDualHttpBinding zapewnia taka sama obsługa protokołów usług internetowych jako WSHttpBinding, ale do użytku z umowy dwustronne. WSDualHttpBinding obsługuje tylko zabezpieczenia SOAP i wymaga niezawodnego przesyłania wiadomości. To Wiązanie wymaga, aby klient miał publiczny URI, który zapewnia wywołanie zwrotne punkt końcowy usługi. To jest dostarczone przez ClientBaseAddress. A podwójne wiązanie ujawnia adres IP klienta do serwisu. Klient powinien stosować zabezpieczenia w celu zapewnienia, że łączy się tylko z usługami, którym ufa.

 1
Author: Mark Coleman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-10 14:28:04

Jeśli serwer nie może wywołać klienta (a zazwyczaj nie powinno), powinieneś zlecić klientowi przeprowadzenie ankiety na serwerze zgodnie z podanymi przez Ciebie wskazówkami. ponieważ masz już fundację WCF, po prostu dodaj operację.

 0
Author: Dani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-09 13:21:08