如何使Websockets在Elm 0.19中工作

时间:2018-08-24 19:00:35

标签: websocket elm

我正在尝试将Elm的版本从0.18升级到0.19。我的项目取决于0.18中的func swiftFunc(input: UnsafePointer<UInt8>!, inputLen: Int32, output: UnsafePointer<UnsafePointer<UInt8>>?, outputLen: UnsafePointer<UInt8>?) { let cfInput = CFDataCreate(kCFAllocatorDefault, input, CFIndex(inputLen)) let cfOutput = // Generate your output. let bufLen = // Determine output buffer length. let buf = UnsafeMutablePointer<UInt8>.allocate(MemoryLayout<UInt8>.stride * bufLen) // Initialize 'buf' with 'cfOutput' somehow. output?.pointee = buf outputLen?.pointee = Int32(bufLen) } 吗?我似乎在0.19中找不到等效的程序包。我想念什么?

2 个答案:

答案 0 :(得分:5)

websocket软件包目前已针对Elm 0.19重新设计,请参见this issue

  

此软件包尚未更新为0.19。我听过很多人说他们需要此软件包中的更多功能,因此我宁愿在更新中将其考虑在内,而不是仅仅做同样的事情。如果您绝对需要此端口,我建议使用端口或0.18。

答案 1 :(得分:5)

这是一个交互式表单的最小工作示例,它使用2个简单的输入/输出端口与elm 0.19模块外部的JavaScript WebSocket对象进行通信,从而从echo.websocket.org回显输入:

文件:echo.elm。编译为:elm make echo.elm --output=echo.js

port module Main exposing (main)

import Browser
import Html exposing (Html)
import Html.Attributes as HA
import Html.Events as HE
import Json.Encode as JE

-- JavaScript usage: app.ports.websocketIn.send(response);
port websocketIn : (String -> msg) -> Sub msg
-- JavaScript usage: app.ports.websocketOut.subscribe(handler);
port websocketOut : String -> Cmd msg

main = Browser.element
    { init = init
    , update = update
    , view = view
    , subscriptions = subscriptions
    }

{- MODEL -}

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

init : () -> (Model, Cmd Msg)
init _ =
    ( { responses = []
      , input = ""
      }
    , Cmd.none
    )

{- UPDATE -}

type Msg = Change String
    | Submit String
    | WebsocketIn String

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
    Change input ->
      ( { model | input = input }
      , Cmd.none
      )
    Submit value ->
      ( model
      , websocketOut value
      )
    WebsocketIn value ->
      ( { model | responses = value :: model.responses }
      , Cmd.none
      )

{- SUBSCRIPTIONS -}

subscriptions : Model -> Sub Msg
subscriptions model =
    websocketIn WebsocketIn

{- VIEW -}

li : String -> Html Msg
li string = Html.li [] [Html.text string]

view : Model -> Html Msg
view model = Html.div []
    --[ Html.form [HE.onSubmit (WebsocketIn model.input)] -- Short circuit to test without ports
    [ Html.form [HE.onSubmit (Submit model.input)]
      [ Html.input [HA.placeholder "Enter some text.", HA.value model.input, HE.onInput Change] []
      , model.responses |> List.map li |> Html.ol []
      ]
    ]

将编译后的echo.js嵌入到echo.html中:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Echo</title>
  <script src="echo.js"></script>
</head>
<body>
  <div id="elm-node"></div>
  <script>
    var app = Elm.Main.init({node: document.getElementById("elm-node")});
    var ws = new WebSocket("wss://echo.websocket.org");
    ws.onmessage = function(message)
    {
        console.log(message);
        app.ports.websocketIn.send(JSON.stringify({data:message.data,timeStamp:message.timeStamp}));
    };
    app.ports.websocketOut.subscribe(function(msg) { ws.send(msg); });
  </script>
</body>
</html>

这在Linux上的Firefox 60.2.0esr上有效,但尚未在其他平台上进行过测试。

同样,这只是一个最小的示例,演示如何将WebSockets与Elm 0.19一起使用端口。它不包括关闭WebSocket,错误处理等。但是希望该示例可以帮助您开始朝这个方向发展。预计Elm很快将再次直接支持WebSockets,因此这只是一个临时解决方法。如果您不需要升级到0.19,请考虑使用0.18。