haskell - 无法将多个客户端与 Haskell Websocket 服务器一起使用
问题描述
我正在尝试使用 websockets 测试我的游戏服务器,但我在使用多个客户端时遇到问题。连接它们中的每一个都可以正常工作,但是当我启动游戏并通过套接字发送第一条消息时,它们会引发“ConnectionClosed”错误。
服务器代码如下所示:
main :: IO ()
main = do
state <- newMVar []
putStrLn "listening"
WS.runServer "127.0.0.1" 9000 $ \pen -> do
c <- WS.acceptRequest pen
putStrLn "user connected"
cs <- takeMVar state
let cs' = c : cs
case Vector.fromList cs' :: Maybe (Vector.Vector 4 WS.Connection) of
Just v -> do
let
us = Vector.imap
(\i x -> websocketUser x ("websocket user " ++ show i))
v
putMVar state []
g <- exampleGame us
_ <- playGame g
return ()
Nothing -> putMVar state cs'
为了测试这一点,我打开了 4 个 chrome 选项卡并将每个选项卡连接到服务器。对于我连接的每个选项卡,服务器都会打印“用户连接”行,在 4 次连接后游戏应该开始,但所有套接字都断开连接。如果我只连接一个客户端,它确实可以正常工作。所以我认为问题在于我连接来自同一台机器的所有客户端。但是我不知道如何在不使用多个设备的情况下进行测试。我已经尝试为每个客户端使用不同的浏览器和端口。
我的问题:这是由来自同一台机器和 chrome 的所有客户端连接还是服务器重用现有连接或类似的东西引起的,如果是,我该如何解决这个问题,以便我可以在本地测试我的游戏?还是我的 Haskell 代码有问题?
解决方案
请参阅ServerApp
类型的文档。IO 操作完成后,底层套接字将关闭。因此,您的前三个客户端中的每一个都接受一个连接,将连接存储在 中state
,然后完成,关闭连接。只有第四个客户端保持它的连接打开,它不能对其他三个连接做任何有用的事情,这些连接现在已经关闭。
如果将最后一行替换为:
Nothing -> do
putMVar state cs'
threadDelay (10^9) -- wait a while
那么这可能会使所有四个客户端都连接起来。
要“真正地”解决这个问题,您可以让前三个连接永远等待,然后安排第四个线程在游戏结束时杀死它们。
但是,我不确定这是正确的架构。您可能希望每个连接线程进入一个循环来处理来自其客户端的传入消息,而不是让唯一的第四个连接线程运行并轮询所有四个连接。这些线程可以修改共享游戏状态和/或直接向其他客户端广播消息(如websockets
文档中的示例“聊天”程序),或者将传入消息排队以供单独的游戏线程处理。
推荐阅读
- java - 尝试使用 Dagger 将架构更改为 MVVM 时遇到问题
- python - 通过 Python 将用户输入的 PC 名称插入到 Windows CMD 关机命令中
- java - 从 Spring Boot 测试中调用的 @Caching 方法 [@Transactional 注释] 不起作用
- php - 在 Woocommerce 中为特定用户角色禁用我的帐户编辑地址
- r - 使用可变列数将长转换为宽
- python - 变量默认值的 Python 快捷方式是另一个变量值(如果它是无)
- c# - 在 C# 泛型中传递“this”在没有强制转换的情况下不起作用
- python - Keras中具有二进制分类的多标签
- django - 需要登录 Django 基于类的视图
- grep - cat + grep 后输出文件比输入文件大得多