Elm - Abonnements

Dans le chapitre précédent, nous avons discuté du fait qu'une vue interagit avec d'autres composants à l'aide de commandes. De même, un composant (par exemple WebSocket) peut parler à une vue à l'aide d'abonnements. Les abonnements permettent à une application Elm de recevoir des entrées externes telles que des événements de clavier, des événements de minuterie et des événements WebSocket.

La figure suivante explique le rôle des abonnements dans une application Elm. L'utilisateur interagit avec une application Elm via des messages. L'application donnée utilise WebSocket et dispose de deux modes de fonctionnement -

  • Envoyer des données côté client au serveur socket via la commande
  • Recevez des données à tout moment du serveur socket via l'abonnement

Syntaxe

La syntaxe pour définir un abonnement est donnée ci-dessous -

type Sub msg

Illustration

Comprenons les abonnements à l'aide d'un exemple simple.

Dans l'exemple ci-dessous, l'application envoie un message au serveur. Le serveur est un serveur d'écho, qui répond au client avec le même message. Tous les messages entrants sont ensuite affichés dans une liste. Nous utiliserons WebSocket (protocole wss) pour être en mesure d'écouter en permanence les messages du serveur. Le WebSocket enverra les entrées utilisateur au serveur en utilisant les commandes tandis qu'il utilisera l'abonnement pour recevoir les messages du serveur.

Les différents composants de l'application sont donnés ci-dessous -

Serveur d'écho

Le serveur d'écho est accessible à l'aide du protocole wss. Le serveur d'écho renvoie l'entrée utilisateur à l'application. Le code pour définir un serveur d'écho est donné ci-dessous -

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

Modèle

Le modèle représente l'entrée utilisateur et une liste de messages entrants du serveur socket. Le code pour définir le modèle est comme indiqué ci-dessous -

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

messages

Le type de message contiendra une entrée pour la saisie de texte de l'utilisateur. Le message Envoyer sera généré lorsque l'utilisateur cliquera sur le bouton pour envoyer le message au serveur WebSocket. Le NewMessage est utilisé lorsque le message arrive du serveur d'écho.

type Msg
   = Input String
   | Send
   | NewMessage String

Vue

La vue de l'application contient une zone de texte et un bouton d'envoi pour envoyer les entrées utilisateur au serveur. La réponse du serveur est affichée sur la vue à l'aide d'une balise 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 ]

Mise à jour

La fonction de mise à jour prend le message et les composants du modèle. Il met à jour le modèle en fonction du type de message.

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. Méthode Signature La description
1 WebSocket.listen listen: String -> (String -> msg) -> Sous msg S'abonne à tous les messages entrants sur un websocket.
2 WebSocket.send send: String -> String -> Cmd msg Envoie une requête wss à une adresse de serveur. Il est important que vous soyez également abonné à cette adresse avec Listen. Si vous ne l'êtes pas, le socket Web sera créé pour envoyer un message, puis fermé.

Abonnement

La fonction d'abonnement prend l'objet de modèle. Pour recevoir les messages du serveur WebSocket, nous appelons WebSocket.listen en transmettant le message en tant que NewMessage . Lorsqu'un nouveau message provient du serveur, la méthode de mise à jour est appelée.

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

principale

La fonction principale est le point d'entrée de l'application elm comme indiqué ci-dessous.

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

Mettre tous ensemble

Step 1 - Créez un répertoire, SubscriptionApp et ajoutez-y un fichier, SubscriptionDemo.elm.

Step 2 - Ajoutez le contenu suivant au fichier 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 - Installez le package websockets à l'aide du gestionnaire de packages elm.

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

Step 4 - Construisez et générez le fichier index.html comme indiqué ci-dessous.

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

Step 5 - Lors de l'exécution, la sortie suivante sera générée -