Elm - Subskrypcje

W poprzednim rozdziale omówiliśmy, że widok współdziała z innymi składnikami za pomocą poleceń. Podobnie składnik (np. WebSocket) może komunikować się z widokiem przy użyciu subskrypcji. Subskrypcje to sposób, w jaki aplikacja Elm może odbierać zewnętrzne dane wejściowe, takie jak zdarzenia klawiatury, zdarzenia licznika czasu i zdarzenia WebSocket.

Poniższy rysunek wyjaśnia rolę subskrypcji w aplikacji Elm. Użytkownik współdziała z aplikacją Elm za pośrednictwem wiadomości. Podana aplikacja korzysta z WebSocket i ma dwa tryby działania -

  • Wyślij dane po stronie klienta do serwera gniazda za pomocą polecenia
  • Odbieraj dane w dowolnym momencie z serwera gniazda za pośrednictwem subskrypcji

Składnia

Składnię definiowania subskrypcji podano poniżej -

type Sub msg

Ilustracja

Zrozummy subskrypcje na prostym przykładzie.

W poniższym przykładzie aplikacja wysyła wiadomość do serwera. Serwer jest serwerem echa, który odpowiada klientowi tą samą wiadomością. Wszystkie przychodzące wiadomości są później wyświetlane na liście. Będziemy używać protokołu WebSocket (protokół wss), aby móc stale nasłuchiwać wiadomości z serwera. WebSocket wyśle ​​dane wejściowe użytkownika do serwera za pomocą poleceń, podczas gdy będzie używać subskrypcji do odbierania wiadomości z serwera.

Poniżej przedstawiono różne elementy aplikacji -

Serwer echa

Dostęp do serwera echo można uzyskać za pomocą protokołu wss. Serwer echa odsyła dane wejściowe użytkownika do aplikacji. Kod definiujący serwer echa jest podany poniżej -

echoServer : String
echoServer =
"wss://echo.websocket.org"

Model

Model reprezentuje dane wejściowe użytkownika i listę komunikatów przychodzących z serwera gniazda. Kod do definiowania Modelu jest podany poniżej -

type alias Model =
   { input : String
   , messages : List String
   }

Wiadomości

Typ wiadomości będzie zawierał dane wejściowe do pobierania tekstu od użytkownika. Wiadomość Wyślij zostanie wygenerowana, gdy użytkownik kliknie przycisk wysyłania wiadomości do serwera WebSocket. NewMessage jest używany, gdy wiadomość przychodzi z serwera echa.

type Msg
   = Input String
   | Send
   | NewMessage String

Widok

Widok aplikacji zawiera pole tekstowe i przycisk przesyłania służący do wysyłania danych wejściowych użytkownika na serwer. Odpowiedź z serwera jest wyświetlana w widoku przy użyciu znacznika DIV .

view : Model -> Html Msg
view model =
   div []
      [ input [onInput Input, value model.input] []
      , button [onClick Send] [text "Send"]
      , div [] (List.map viewMessage (List.reverse model.messages))
      ]

viewMessage : String -> Html msg
viewMessage msg =
   div [] [ text msg ]

Aktualizacja

Funkcja aktualizacji przejmuje wiadomość i komponenty modelu. Aktualizuje model na podstawie typu wiadomości.

update : Msg -> Model -> (Model, Cmd Msg)
update msg {input, messages} =
   case msg of
      Input newInput ->
         (Model newInput messages, Cmd.none)

   Send ->
      (Model "" messages, WebSocket.send echoServer input)

   NewMessage str ->
      (Model input (str :: messages), Cmd.none)
Sr. No. metoda Podpis Opis
1 WebSocket.listen słuchaj: String -> (String -> msg) -> Sub msg Subskrybuje wszystkie przychodzące wiadomości w sieci Web.
2 WebSocket.send send: String -> String -> Cmd msg Wysyła żądanie wss na adres serwera. Ważne jest, aby subskrybować również ten adres z odsłuchiwaniem. Jeśli nie, zostanie utworzone gniazdo sieciowe do wysyłania jednej wiadomości, a następnie zamknięte.

Subskrypcja

Funkcja subskrypcji przyjmuje obiekt modelu. Aby odebrać wiadomości z serwera WebSocket, wywołujemy WebSocket.listen przekazując wiadomość jako NewMessage . Kiedy nowa wiadomość pochodzi z serwera, wywoływana jest metoda aktualizacji.

subscriptions : Model -> Sub Msg
subscriptions model =
WebSocket.listen echoServer NewMessage

Główny

Główną funkcją jest punkt wejścia do aplikacji elm, jak pokazano poniżej.

main =
   Html.program
      { init = init
      , view = view
      , update = update
      , subscriptions = subscriptions
      }

Kładąc wszystko razem

Step 1 - Utwórz katalog, SubscriptionApp i dodaj do niego plik SubscriptionDemo.elm.

Step 2 - Dodaj następującą zawartość do pliku SubscriptionDemo.elm -

import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import WebSocket

main =
   Html.program
      { init = init
      , view = view
      , update = update
      , subscriptions = subscriptions
      }

echoServer : String
echoServer =
   "wss://echo.websocket.org"

-- MODEL

type alias Model =
   { input : String
   , messages : List String
   }

init : (Model, Cmd Msg)
init =
   (Model "" [], Cmd.none)

-- UPDATE
type Msg
   = Input String
   | Send
   | NewMessage String

update : Msg -> Model -> (Model, Cmd Msg)
update msg {input, messages} =
   case msg of
      Input newInput ->
      (Model newInput messages, Cmd.none)

   Send ->
      (Model "" messages, WebSocket.send echoServer input)

   NewMessage str ->
      (Model input (str :: messages), Cmd.none)

-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
   WebSocket.listen echoServer NewMessage

-- VIEW
view : Model -> Html Msg
view model =
   div []
      [ input [onInput Input, value model.input] []
      , button [onClick Send] [text "Send"]
      , div [] (List.map viewMessage (List.reverse model.messages))
      ]

viewMessage : String -> Html msg
viewMessage msg =
div [] [ text msg ]

Step 3 - Zainstaluj pakiet websockets za pomocą menedżera pakietów elm.

C:\Users\dell\elm\SubscriptionApp> elm-package install elm-lang/websocket

Step 4 - Zbuduj i wygeneruj plik index.html, jak pokazano poniżej.

C:\Users\dell\elm\SubscriptionApp> elm make .\SubscriptionDemo.elm

Step 5 - Po wykonaniu wygenerowane zostanie następujące wyjście -