Учебники

Вяз — Подписки

В предыдущей главе мы обсуждали, что представление взаимодействует с другими компонентами с помощью команд. Аналогично, компонент (например, WebSocket) может взаимодействовать с представлением с использованием подписок. Подписки — это способ, которым приложение Elm может получать внешние входные данные, такие как события клавиатуры, события таймера и события WebSocket.

На следующем рисунке показана роль подписок в приложении Elm. Пользователь взаимодействует с приложением Elm через сообщения. Данное приложение использует WebSocket и имеет два режима работы:

  • Отправить данные на стороне клиента на сервер сокетов с помощью команды
  • Получать данные в любое время с сервера сокетов через подписку

сервер сокетов

Синтаксис

Синтаксис для определения подписки приведен ниже —

type Sub msg

иллюстрация

Давайте разберемся с подписками на простом примере.

В приведенном ниже примере приложение отправляет сообщение на сервер. Сервер является эхо-сервером, который отвечает клиенту тем же сообщением. Все входящие сообщения позже отображаются в списке. Мы будем использовать WebSocket (протокол wss), чтобы иметь возможность непрерывно прослушивать сообщения с сервера. WebSocket будет отправлять пользовательский ввод на сервер с помощью команд, в то время как он будет использовать подписку для получения сообщений от сервера.

Различные компоненты приложения приведены ниже —

Эхо сервер

Доступ к эхо-серверу можно получить по протоколу wss. Эхо-сервер отправляет обратно пользовательский ввод в приложение. Код для определения эхо-сервера приведен ниже —

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

модель

Модель представляет вводимые пользователем данные и список входящих сообщений с сервера сокетов. Код для определения модели приведен ниже.

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

Сообщения

Тип сообщения будет содержать Ввод для ввода текста от пользователя. Сообщение Send будет сгенерировано, когда пользователь нажмет кнопку, чтобы отправить сообщение на сервер WebSocket. NewMessage используется, когда сообщение приходит с эхо-сервера.

type Msg
   = Input String
   | Send
   | NewMessage String

Посмотреть

Вид приложения содержит текстовое поле и кнопку отправки для отправки пользовательского ввода на сервер. Ответ от сервера отображается в представлении с использованием тега 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 ]

Обновить

Функция обновления принимает сообщение и компоненты модели. Обновляет модель в зависимости от типа сообщения.

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)
Старший метод Подпись Описание
1 WebSocket.listen прослушать: String -> (String -> msg) -> Sub msg Подписывается на любые входящие сообщения на веб-сокете.
2 WebSocket.send отправить: String -> String -> Cmd msg Отправляет запрос wss на адрес сервера. Важно, чтобы вы также подписались на этот адрес с помощью listen. Если нет, веб-сокет будет создан для отправки одного сообщения, а затем закрыт.

Подписка

Функция подписки принимает объект модели. Чтобы получать сообщения от сервера WebSocket, мы вызываем WebSocket.listen, передавая сообщение как NewMessage . Когда с сервера приходит новое сообщение, вызывается метод обновления.

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

главный

Основная функция — это точка входа в приложение elm, как показано ниже.

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

Собираем все вместе

Шаг 1 — Создайте каталог SubscriptionApp и добавьте в него файл SubscriptionDemo.elm.

Шаг 2 — Добавьте следующее содержимое в файл 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 ]

Шаг 3 — Установите пакет websockets с помощью менеджера пакетов elm.

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

Шаг 4 — Создайте и сгенерируйте файл index.html, как показано ниже.

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

Шаг 5 — После выполнения будет сгенерирован следующий вывод: