Zakoduj ankietę w czasie rzeczywistym za pomocą HTML5 WebSockets

Ten artykuł pojawił się po raz pierwszy w nr 217 magazynu .net - najlepiej sprzedającego się na świecie magazynu dla projektantów i programistów stron internetowych.

WebSockets są częścią specyfikacji HTML5, a najprościej można na nie spojrzeć, ponieważ wyznaczają standard tworzenia długotrwałych dwukierunkowych połączeń między przeglądarką a serwerem. Dzięki temu połączeniu przeglądarki mogą wysyłać wiadomości z powrotem do serwera (jak szybszy Ajax), a co ważniejsze, serwer może wysyłać nowe informacje do podłączonych klientów, gdy staną się dostępne. WebSockets pozwalają na komunikację z ekstremalnie niskimi opóźnieniami przy niewielkim narzucie.

Od wielu lat istnieją techniki przesyłania danych do połączonych klientów, które zostały zgrupowane pod terminem Kometa (zob. pl.wikipedia.org/wiki/Comet_(programming) dla szczegółów). Jednak WebSockets tworzą znacznie prostszy i znormalizowany sposób robienia tego i prawdopodobnie zrewolucjonizują sposób, w jaki ludzie budują interfejsy czasu rzeczywistego. Na tym etapie WebSockets są kompatybilne z kilkoma nowoczesnymi przeglądarkami, a dla tych, którzy jeszcze nie weszli na pokład, dostępne są opcje awaryjne Flash.

Po co ich używać? WebSockets umożliwiają znacznie łatwiejsze tworzenie doświadczeń użytkowników w czasie rzeczywistym. Ludzie przyzwyczaili się już do natychmiastowości w aplikacjach, z których regularnie korzystają, i chcą czuć się połączeni z innymi osobami korzystającymi z usługi. Pojawienie się czatu na Facebooku, gier online dla wielu graczy, aktualizacji w czasie rzeczywistym na Twitterze i wspólnego edytowania za pośrednictwem Dokumentów Google utorowało drogę aplikacjom na kilka następnych lat. Tego typu doświadczenia użytkowników będą zyskiwać na popularności, a technologia WebSockets będzie ich podstawą. Coraz ważniejsza będzie wiedza, jak budować tego rodzaju interfejsy.

Jak ich używać

Jak więc używamy tej niesamowitej nowej technologii? W przeciwieństwie do innych części specyfikacji HTML5, WebSockets wymaga zarówno klienta, jak i serwera. Dlatego ich uruchomienie i uruchomienie nie jest tak proste, jak w przypadku wideo, kanwy, geolokalizacji czy kontrolek formularzy. Nie zniechęcaj się jednak, ponieważ istnieje wiele opcji, od których możesz zacząć.

Pierwsza dostępna metoda polega na zainstalowaniu i utrzymaniu własnego serwera gniazd. Istnieją projekty open source, takie jak Gniazdo IO , które są dość łatwe do rozpoczęcia. Jednak zainstalowanie tego typu serwerów gniazd w przeciętnym środowisku hostingu nie zawsze jest łatwe ze względu na narzucone ograniczenia bezpieczeństwa hostingu i zmniejszoną alokację zasobów dla długotrwałych połączeń, których wymagają WebSockets.

Inną opcją jest skorzystanie z usługi hostowanej, która integruje się z istniejącą infrastrukturą witryny internetowej. To właśnie zapewnia moja firma Pusher.

Jeśli chodzi o samouczki, skorzystam z naszej usługi, ponieważ interfejs API WebSocket jest nieco „nieosłonięty”, a warstwa abstrakcji może ułatwić zrozumienie komunikacji między klientem a serwerem.

Warstwy abstrakcji mogą również zarządzać typowymi scenariuszami, takimi jak obsługa zrywanych połączeń i ponownego łączenia, a także mogą dodawać bogatsze funkcje i funkcjonalność. Na przykład bibliotekę opakowującą WebSockets można uznać za podobną do sposobu, w jaki jQuery zawija dostęp do podstawowych operacji na DOM; myśleć document.getElementById („myDiv”) a jQuery („# myDiv”) .

Jak oni wyglądają?

Kiedy mówimy, że WebSockets są częścią specyfikacji HTML5, niekoniecznie jest jasne, co to oznacza. W praktyce nie oznacza to zmiany w kodzie HTML strony, ale raczej funkcjonalność jest udostępniana za pośrednictwem nowych interfejsów API JavaScript. Pierwszą nowością jest obiekt WebSocket zainicjowany adresem URL, z którym ma się połączyć:

var ws = new WebSocket('ws://example.com');

Ten obiekt WebSocket ma kilka zdarzeń, których można użyć, aby podłączyć się do reszty kodu. Główne zdarzenia mają miejsce, gdy połączenie jest otwierane, zamykane i przychodzą nowe wiadomości.

socket.onopen = function(evt) { alert('Connection established') } socket.onclose = function(evt){ alert('Connection closed') } socket.onmessage = function(evt){ alert('I got data: ' + evt.data) }

Możesz również przesyłać dane przez połączenie:

socket.send( 'Have some data' );

Miejmy nadzieję, że na podstawie powyższego ograniczonego kodu można zobaczyć, jak Twitter mógłby na przykład nawiązać połączenie WebSocket, które otrzymywałoby nowe tweety w miarę ich pojawiania się, aby mogły być wyświetlane na stronie.

Tworzenie ankiety w czasie rzeczywistym

Aby zademonstrować bardziej szczegółowe zastosowanie, wziąłem przykład z ankiety w czasie rzeczywistym. Gdyby to była pełna aplikacja, prawdopodobnie byłoby kilka rzeczy, które zrobiłbym inaczej, ale pozwoli mi to pokazać, jak przydatne są WebSockets.

W tym przykładzie nasza aplikacja zadaje proste pytanie „Jaki jest najlepszy język?” I udostępnia przyciski umożliwiające użytkownikowi dokonanie wyboru. Nad przyciskami wyświetlany jest wykres, który śledzi popularność różnych odpowiedzi. Ciekawsze jest to, że wyniki zmieniają się w czasie rzeczywistym, gdy głosują ludzie w innych przeglądarkach.

Będę używać Ruby na serwerze i postaram się, aby wszystko było całkiem proste, abyśmy mogli skupić się na interakcji WebSocket. Będę również używał Pushera dla serwera WebSocket, ponieważ dodaje obsługę zastępczą dla starszych przeglądarek. Kod źródłowy można znaleźć na Github . Dla tych, którzy chcą zacząć od stworzenia podstawowej aplikacji, zajrzyj do sekcji Pierwsze kroki. Jeśli wolisz wskoczyć w dodanie funkcji czasu rzeczywistego, pobierz podstawową aplikację .

Pierwsze kroki

Najpierw musimy stworzyć naszą podstawową aplikację ankietową Railsów. Potrzebujemy bazy danych, a SurveyEntry model, a SurveyEntries kontroler i widok do wyświetlania wyników. W Ruby on Rails można to łatwo zrobić. Otwórz wiersz polecenia lub okno terminala i wprowadź następujące polecenia:

rails new realtime_survey - utwórz nową aplikację
cd realtime_survey - przejdź do nowego katalogu aplikacji
rake db: create - utwórz bazę danych
railsy generują model SurveyEntry choice: string - utwórz plik SurveyEntry Model
railsy generują kontroler Tworzenie indeksu SurveyEntries - utwórz kontroler SurveyEntries z akcjami o nazwie indeks i Stwórz
rake db: migracja - utwórz plik Survey_entries tabela w bazie danych dla modelu SurveyEntry

Na index.html.erb plik powinien zostać utworzony w ramach / app / views / survey_entries teczka. To reprezentuje widok dla akcji indeksu SurveyEntries kontroler. Jeśli jest obecny, usuń plik index.html plik znaleziony w app / public katalog i zaktualizuj /config/routes.rb tak, aby akcja indeksu w SurveyController jest wywoływana domyślnie.

RealtimeSurvey::Application.routes.draw doroot :to => 'survey_entries#index' resources :survey_entries end

Jeśli uruchomisz serwer railsowy polecenie z realtime_survey katalogu i przejdź do http: // localhost: 3000 zobaczysz zawartość index.html.erb widok. Dodajmy również kod, który pobiera liczbę głosów na język z bazy danych, dodając metodę do SurveyEntry Model ( Survey_entry.rb ). Zdefiniujemy również opcje języka programowania w modelu.

class SurveyEntry :choice }) FORM_OPTIONS.map do |o| end end end

Następnie powinniśmy wywołać ten kod z naszego kontrolera i udostępnić nam dane wejściowe do ankiety.

class SurveyEntriesController params[:choice]) redirect_to '/' endend

Na koniec powinniśmy zaktualizować nasz widok indeksu wpisów w ankietach, aby wyświetlić wyniki ankiety i opcje języka programowania.