我一直在使用 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 中:
Event
关闭 websockets s,见 _webSocketConfig_close
_webSocketConfig_reconnect
Event
当连接关闭时暴露,见 _webSocket_close
Event
发生错误时暴露,参见 _webSocket_error
我相信 close 事件正是您想要的。只是当时不可用。
关于haskell - 通过reflex-dom中的websockets检测关闭的服务器连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35801111/