"输入未定义"在Elm中使用WebSockets时出错

时间:2015-04-09 00:24:21

标签: websocket elm

我正在尝试使用Elm中的WebSockets设置一个简单的示例,但我一直得到运行时错误“输入未定义”。控制台没有在我的elm文件或类似内容中给我任何行号。

我试图在一个大项目中使用WebSockets,并且我不断收到错误“a is undefined”,所以我决定用这个小例子来尝试找出问题。

我写了一些代码来接收包含来自websocket的数字的消息。它会递增数字,然后通过Web套接字将新数字发回。服务器执行相同的操作,将递增1的数字发送回客户端。

这是榆树代码:

import Graphics.Element (Element)
import Signal
import Signal (Signal)
import Text
import Window
import WebSocket
import String

type State = Num Int
           | StateErr String

input : Signal String
input =
    WebSocket.connect "ws://localhost:4567/test" sendToServer

sendToServer : Signal String
sendToServer =
    Signal.dropRepeats
        (Signal.dropIf (\str -> str == "") "" (Signal.map formatReply state))

formatReply : State -> String
formatReply state =
    case state of
        Num n -> toString n
        StateErr str -> ""


stepState : String -> State -> State
stepState str state =
    case (String.toInt str) of
        Ok n -> Num (n + 1)
        Err str -> StateErr str


display : (Int,Int) -> State -> Element
display (w,h) state = Text.asText state


state : Signal State
state =
    Signal.foldp stepState (Num 0) input


main : Signal Element
main =
    Signal.map2 display Window.dimensions state

我测试了服务器端,它工作正常,所以我绝对不认为服务器导致了这个问题。

当我在Firefox中尝试代码时,我得到“输入未定义”。当我在Chrome中运行它时,我得到“无法读取未定义的属性'孩子'”。 在Chrome中,在查看堆栈跟踪时,似乎代码运行时,输入未定义。这是WebSocket库的错误吗?

我很擅长使用Elm,所以我很感激有关使用websockets的任何帮助/建议。

2 个答案:

答案 0 :(得分:3)

我了解到我的麻烦的原因是,截至目前,elm中的WebSockets库尚未完全实现。我还了解到我可以使用ports实现目标,然后在javascript中实现websocket。

我将以下javascript添加到我的html文件中:

var game = Elm.fullscreen(Elm.SlimeWarz, {rawServerInput: ""});
var socket = new WebSocket("ws://localhost:4567");

socket.onopen = function(){
  console.log("Socket has been opened.");
}

socket.onmessage = function(msg){
  game.ports.rawServerInput.send(msg.data);
}

game.ports.sendToServer.subscribe(sendOverWebsocket);

function sendOverWebsocket(str) {
  socket.send(str);
}

然后在elm中,我可以使用名为sendtoServer

的移植信号发送数据
port sendToServer : Signal String

我可以查看通过移植信号rawServerInput

收到的所有数据
port rawServerInput : Signal String

答案 1 :(得分:3)

答案

我将使用my answer to this question的一部分。 我认为your solution使用端口并使用JavaScript中的websocket部分比我在该答案中描述的黑客更好,但您可能仍希望查看它。一旦Elm 0.15被释放,这个问题应该完全消失,因为语言功能和Websocket的改进(Http得到了改进)。

上下文:错误原因

您收到运行时错误的原因是compiler bug。编译器只在递归函数上生成正确的代码,而它接受任何递归值。请注意,您的input取决于sendToServersendToserver取决于state,而sContext: tate取决于input

上下文:代码架构

这些循环信号通常是程序架构不良的标志。您可以找到有关该主题的更多信息here但是你的架构在这里没有错。问题在于Websocket库不能引导你朝着正确的方向前进。