📜  Elm-订阅

📅  最后修改于: 2020-11-04 09:05:55             🧑  作者: Mango


 

在上一章中,我们讨论了View使用Command与其他组件交互的情况。同样,组件(例如WebSocket)可以使用订阅与View对话。订阅是Elm应用程序可以接收外部输入(例如键盘事件,计时器事件和WebSocket事件)的一种方式。

下图说明了订阅在Elm应用程序中的作用。用户通过消息与Elm应用程序进行交互。给定的应用程序使用WebSocket,并且具有两种操作模式-

  • 通过Command将客户端数据发送到套接字服务器
  • 随时通过订阅从套接字服务器接收数据

套接字服务器

句法

下面给出了定义订阅的语法-

type Sub msg

插图

让我们使用一个简单的示例了解订阅。

在下面给出的示例中,应用程序将消息发送到服务器。该服务器是回显服务器,它以相同的消息响应客户端。以后,所有传入消息都显示在列表中。我们将使用WebSocket(wss协议)来持续监听来自服务器的消息。 WebSocket将使用命令将用户输入发送到服务器,同时将使用订阅从服务器接收消息。

该应用程序的各个组件在下面给出-

回声服务器

可以使用wss协议访问回显服务器。回显服务器将用户输入发送回应用程序。下面给出了定义回显服务器的代码-

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

模型

该模型表示用户输入和来自套接字服务器的传入消息列表。定义模型的代码如下:

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

留言内容

消息类型将包含“输入”,以接受用户的文本输入。当用户单击按钮将消息发送到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)
Sr. No. Method Signature Description
1 WebSocket.listen listen : String -> (String -> msg) -> Sub msg Subscribes to any incoming messages on a websocket.
2 WebSocket.send send : String -> String -> Cmd msg Sends a wss request to a server address. It is important that you are also subscribed to this address with listen. If you are not, the web socket will be created to send one message and then closed.

订阅

预订函数接受模型对象。为了从WebSocket服务器接收消息,我们调用WebSocket.listen ,将消息作为NewMessage传递。从服务器收到新消息时,将调用update方法。

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-使用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-执行后,将生成以下输出-

订阅应用