Programowanie w SignalR daje właśnie taki model ideowy zapewniając dobór technologii odpowiadającej możliwościom urządzenia klienckiego. Serwisy typu push są w SignalR zaimplementowane na cztery sposoby, rozpoczynając od tych najmniej wydajnych, a kończąc na najwydajniejszych:
- Long polling - mechanizm cyklicznego odpytywania serwera AJAX-owymi zapytaniami. Zapytanie takie ma ustawiony długi timeout (np. 30 sekund), a serwer nie odpowiada na nie od razu, ale w momencie, gdy pojawią mu się jakieś dane do wysłania. Jeżeli serwer nie ma nic ciekawego do wysłania, to nie wysyła odpowiedzi, a klient ponowi żądanie za 30 sekund
- Forever frame - po stronie klienta pojawia się ukryty iFrame, który wysyła zapytanie do serwera. Serwer zwraca odpowiedzi z nagłówkiem Transfer-encoding: chunked, który pozwala na wysłanie odpowiedzi w kilku paczkach. Każda taka wiadomość jest wysyłana tylko wtedy, kiedy na serwerze pojawią się nowe dane. Serwer wysyła wiadomości, które wstrzykują skrypt wywołujący jakąś metodę po stronie klienta.
- Server-sent events - jednokierunkowy model komunikacji, w którym serwer wysyła do klienta zdarzenia. Wykorzystuje ideę persistent connection (reużywania połączenia TCP do wysłania wielu requestów / responsów w oparciu o nagłówek connection: 'keep-alive'). Wiadomości takie wykorzystują specjalny content-type: text/event-stream, a po stronie klienta także obiekt EventSource
- WebSocket - komunikacja dwukierunkowa, oparta na prostym API WebSocket ze specyfikacji HTML5. Przeglądarka negocjuje z serwerem upgrade protokołu z HTTP/HTTPS na odpowiednio WS lub WSS i jeżeli serwer wyrazi zgodę (kod HTTP 101), to połaczenie TCP/IP zostanie użyte do otwarcia dwukierunkowego kanału pomiędzy klientem, a serwerem. Po stronie JS mamy do dyspozycji obiekt WebSocket.
Następnie tworzymy najprostszy rodzaj huba - echo, które będzie odpowiadało na klienckie wiadomości.
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { using (WebApp.Start<WsStartup>("http://localhost:1968")) { Console.WriteLine("Server running!"); Console.ReadLine(); } } } public class WsStartup { public void Configuration(IAppBuilder app) { app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); app.MapSignalR(); } } [HubName("echo")] public class EchoHub : Hub { public string Call(string text) { return text + " from hub"; } } }
Wywołanie metody WebApp.Start
<!DOCTYPE html> <html > <head> <title></title> <script src="Scripts/jquery-2.1.0.js"></script> <script src="Scripts/jquery.signalR-2.0.2.js"></script> <script src="/signalr/hubs"></script> <script> $(function () { var hub = $.connection.echo; $.connection.hub .start() .done(function () { hub.server.call('Hello SignalR!').done(function(msg){ alert(msg); });; }); }); </script> </head> <body> </body> </html>
Trzeci tag <script> wskazuje na dynamiczny endpoint /signalr/hubs wystawiony przez serwer. Endpoint ten generuje w locie kod JS na podstawie dostępnych hubów. Dzięki niemu możemy pobrać referencję do naszego huba ($.connection.echo). Następnie w asynchroniczny sposób zostaje wołana metoda start. Metoda ta zwraca obiekt promise, w którym możemy zasubskrybować się na metodzie done, gdzie możemy wołać kod z naszego huba.
Brak komentarzy:
Prześlij komentarz