我一直在使用reflex和reflex-dom重新创建一个桌面游戏的网页版本,到目前为止我非常喜欢它,但我需要一个websocket来提醒玩家当另一个玩家做出移动时.
一切都很好,但如果服务器出现故障,我找不到检测它发生的方法并重新连接.此外,如果您在服务器关闭时将事件发送到服务器,它就会被吃掉,而不会出现任何错误.
我正在使用https://github.com/reflex-frp/reflex-examples/blob/master/websocket-echo/src/Main.hs的websockets示例的精简版本
{-# LANGUAGE RecursiveDo #-}
module Lib where
import Data.Monoid
import Reflex.Dom
import qualified Data.Text as T
import Data.Text.Encoding (encodeUtf8, decodeUtf8)
wsurl = "ws://127.0.0.1:5714"
-- wsurl = "ws://echo.websocket.org"
someFunc = mainWidget $do
rec t <- textInput $def & setValue .~ fmap (const "") newMessage
b <- button "Send"
text $"Sending to " <> wsurl
let newMessage = fmap ((:[]) . encodeUtf8 . T.pack) $tag (current $value t) $leftmost [b, textInputGetEnter t]
ws <- webSocket wsurl $def & webSocketConfig_send .~ newMessage
receivedMessages <- foldDyn (\m ms -> ms ++ [m]) [] $_webSocket_recv ws
el "p" $text "Responses from :"
_ <- el "ul" $simpleList receivedMessages $\m -> el "li" $dynText =<< mapDyn (T.unpack . decodeUtf8) m
return ()
我觉得应该有一种方法可以使用tickLossy来发送带有超时的ping,比如一些动态会返回websockets然后重新连接,如果ping有一定的时间而没有响应?但我无法想象重新连接的代码会是什么样子.
编辑:当websocket仍处于挂起状态时,reflex-dom发送事件是一个问题.我做了一个拉取请求,虽然我觉得某处有更好的解决方案.
最佳答案
Edit: It was an issue with reflex-dom sending an event while a
websocket was still in the pending state. I made a pull request,
although I feel there is a better solution somewhere.
仅供参考,自问题发布以来,WebSocket API的一些非常相关的扩展已合并到reflex-dom中:
>您可以通过事件关闭websockets,请参阅_webSocketConfig_close
>您可以指定是否要自动重新连接,请参阅_webSocketConfig_reconnect
>连接关闭时会显示一个事件,请参阅_webSocket_close
>发生错误时会显示一个事件,请参阅_webSocket_error
我相信近距离赛事正是你所寻找的.它当时还没有.