Elm - Assinaturas

No capítulo anterior, discutimos que uma View interage com outros componentes usando comandos. Da mesma forma, um componente (por exemplo, WebSocket) pode se comunicar com uma visualização usando assinaturas. As assinaturas são uma forma de um aplicativo Elm receber entradas externas, como eventos de teclado, eventos de timer e eventos WebSocket.

A figura a seguir explica a função das assinaturas em um aplicativo Elm. O usuário interage com um aplicativo Elm por meio de mensagens. O aplicativo fornecido usa WebSocket e tem dois modos de operação -

  • Envie dados do lado do cliente para o servidor de soquete via comando
  • Receba dados a qualquer momento do servidor de soquete por meio de assinatura

Sintaxe

A sintaxe para definir uma assinatura é fornecida abaixo -

type Sub msg

Ilustração

Vamos entender as assinaturas usando um exemplo simples.

No exemplo abaixo, o aplicativo envia uma mensagem ao servidor. O servidor é um servidor de eco, que responde ao cliente com a mesma mensagem. Todas as mensagens recebidas são posteriormente exibidas em uma lista. Usaremos WebSocket (protocolo wss) para poder escutar continuamente as mensagens do servidor. O WebSocket enviará a entrada do usuário para o servidor usando Comandos, enquanto ele usará Assinatura para receber mensagens do servidor.

Os vários componentes do aplicativo são fornecidos abaixo -

Servidor Echo

O servidor de eco pode ser acessado usando o protocolo wss. O servidor de eco envia de volta a entrada do usuário para o aplicativo. O código para definir um servidor de eco é fornecido abaixo -

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

Modelo

O modelo representa a entrada do usuário e uma lista de mensagens de entrada do servidor de soquete. O código para definir o modelo é fornecido abaixo -

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

Mensagens

O tipo de mensagem conterá entrada para obter a entrada de texto do usuário. A mensagem Enviar será gerada quando o usuário clicar no botão para enviar mensagem ao servidor WebSocket. O NewMessage é usado quando a mensagem chega do servidor de eco.

type Msg
   = Input String
   | Send
   | NewMessage String

Visão

A visualização do aplicativo contém uma caixa de texto e um botão de envio para enviar a entrada do usuário ao servidor. A resposta do servidor é exibida na Visualização usando uma tag 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 ]

Atualizar

A função de atualização leva a mensagem e os componentes do modelo. Ele atualiza o modelo com base no tipo de mensagem.

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. Não. Método Assinatura Descrição
1 WebSocket.listen ouvir: String -> (String -> msg) -> Sub msg Assina todas as mensagens recebidas em um websocket.
2 WebSocket.send enviar: String -> String -> Cmd msg Envia uma solicitação wss para um endereço de servidor. É importante que você também esteja inscrito neste endereço para ouvir. Se não estiver, o web socket será criado para enviar uma mensagem e depois fechado.

Inscrição

A função de assinatura aceita o objeto de modelo. Para receber as mensagens do servidor WebSocket, chamamos WebSocket.listen passando a mensagem como NewMessage . Quando uma nova mensagem chega do servidor, o método de atualização é chamado.

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

a Principal

A função principal é o ponto de entrada para o aplicativo olm, conforme mostrado abaixo.

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

Juntando tudo

Step 1 - Crie um diretório, SubscriptionApp e adicione um arquivo, SubscriptionDemo.elm a ele.

Step 2 - Adicione o seguinte conteúdo ao arquivo 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 - Instale o pacote websockets usando o gerenciador de pacotes elm.

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

Step 4 - Construa e gere o arquivo index.html conforme mostrado abaixo.

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

Step 5 - Após a execução, a seguinte saída será gerada -