В предыдущей главе мы обсуждали, что представление взаимодействует с другими компонентами с помощью команд. Аналогично, компонент (например, 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 — После выполнения будет сгенерирован следующий вывод: