Elm - 订阅
在上一章中,我们讨论了视图使用命令与其他组件交互。 类似地,组件(例如 WebSocket)可以使用订阅与视图通信。 订阅是 Elm 应用程序接收键盘事件、计时器事件和 WebSocket 事件等外部输入的一种方式。
下图解释了订阅在 Elm 应用程序中的作用。 用户通过消息与 Elm 应用程序交互。 给出的应用程序使用WebSocket,它有两种操作模式 −
- 通过Command向socket服务器发送客户端数据
- 通过订阅随时从套接字服务器接收数据
语法
定义订阅的语法如下 −
type Sub msg
示例
让我们通过一个简单的示例来了解订阅。
在下面给出的示例中,应用程序向服务器发送一条消息。 服务器是一个回显服务器,它用相同的消息响应客户端。 所有传入的消息稍后都会显示在列表中。 我们将使用WebSocket(wss协议)来持续监听来自服务器的消息。 WebSocket 将使用命令将用户输入发送到服务器,同时它将使用订阅从服务器接收消息。
下面给出了应用程序的各个组件 −
echo 回显服务器
可以使用wss协议访问echo回显服务器。 回显服务器将用户输入发送回应用程序。 下面给出定义 echo 回显服务器的代码 −
echoServer : String echoServer = "wss://echo.websocket.org"
模型
该模型表示用户输入和来自套接字服务器的传入消息列表。 定义Model的代码如下 −
type alias Model = { input : String , messages : List String }
消息
消息类型将包含用于从用户处获取文本输入的输入。 当用户单击按钮向 WebSocket 服务器发送消息时,将生成发送消息。 当消息从 echo 服务器到达时使用 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)
Sr. No. | 方法 | 标记 | 描述 |
---|---|---|---|
1 | WebSocket.listen | listen : String -> (String -> msg) -> Sub msg | 订阅网络套接字上的任何传入消息。 |
2 | WebSocket.send | send : String -> String -> Cmd msg | 向服务器地址发送 wss 请求。 重要的是您也订阅了这个地址并收听。 如果没有,将创建 Web 套接字来发送一条消息,然后关闭。 |
订阅
订阅函数接收模型对象。 为了从 WebSocket 服务器接收消息,我们调用 WebSocket.listen 将消息作为 NewMessage 传递。 当服务器收到新消息时,将调用 update 方法。
subscriptions : Model -> Sub Msg subscriptions model = WebSocket.listen echoServer NewMessage
main
main函数是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 − 使用 elm 包管理器安装 websockets 包。
C:\Users\dell\elm\SubscriptionApp> elm-package install elm-lang/websocket
步骤 4 − 构建并生成index.html文件,如下所示。
C:\Users\dell\elm\SubscriptionApp> elm make .\SubscriptionDemo.elm
步骤 5 − 执行后,将生成以下输出 −