我正在尝试使用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的任何帮助/建议。
答案 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
取决于sendToServer
,sendToserver
取决于state
,而sContext: tate
取决于input
。
这些循环信号通常是程序架构不良的标志。您可以找到有关该主题的更多信息here。 但是你的架构在这里没有错。问题在于Websocket
库不能引导你朝着正确的方向前进。