我一直在使用 reflex 和 reflex-dom 来重新创建棋盘游戏的 web 版本,到目前为止我非常喜欢它,但是我需要一个 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 发送事件是一个问题。我提出了拉取请求,尽管我觉得某处有更好的解决方案。