Concurrency clojure.core.async是否适合通过WebSocket同步游戏状态和用户输入?(循环运行一次/100ms)

Concurrency clojure.core.async是否适合通过WebSocket同步游戏状态和用户输入?(循环运行一次/100ms),concurrency,clojure,websocket,future,game-loop,Concurrency,Clojure,Websocket,Future,Game Loop,我有一个小的Clojure游戏(想想蛇,但多人游戏;如果你碰到另一条蛇,你就输了)运行在WebSockets上-逻辑在Clojure后端,渲染在浏览器中 游戏的每个“回合”都需要100毫秒,在此期间,游戏的步骤s涉及1)计算游戏的下一个状态,2)通过WebSocket将游戏状态发送给每个玩家3)检查游戏是否结束,如果不是4)睡眠100毫秒减去执行步骤1-3所需的时间,以及5)循环返回到1 有一个全局atomgames,它是从UUID到游戏地图的地图(具有玩家坐标、方向等)。当玩家按下箭头键时,浏

我有一个小的Clojure游戏(想想蛇,但多人游戏;如果你碰到另一条蛇,你就输了)运行在WebSockets上-逻辑在Clojure后端,渲染在浏览器中

游戏的每个“回合”都需要100毫秒,在此期间,游戏的
步骤
s涉及1)计算游戏的下一个状态,2)通过WebSocket将游戏状态发送给每个玩家3)检查游戏是否结束,如果不是4)睡眠100毫秒减去执行步骤1-3所需的时间,以及5)循环返回到1

有一个全局atom
games
,它是从UUID到游戏地图的地图(具有玩家坐标、方向等)。当玩家按下箭头键时,浏览器会发送一条包含游戏UUID、玩家UUID和移动的消息。在收到该消息(独立于游戏循环)时,服务器直接修改games atom,以更新其
到moves
映射,表示具有某个UUID的玩家想要转向
:right
。上面的步骤1)在向前移动每个玩家(每100毫秒)之前,获取移动列表并相应地更改每个玩家的方向。这种方法有效

我学习了core.async(go、channels、parking等),但我不确定它是否适用于这种情况。我最初的想法是,我有一个缓冲通道来代替
:移动
地图作为游戏的一部分。然后,当玩家提交移动时,我可以执行
(>!!ch[:left])
,例如。当我计算下一场比赛时,我可以用( 这更像是一个学习项目,所以如果core.async与我当前的方法基本相同,那很好。但是它首先适用吗


谢谢。

首先,我假设当您说“在websocket上运行”时,您的意思是在浏览器中运行ClojureScript,并且您希望在浏览器中使用core.async将websocket通信实现与事件生成分离

在这种情况下,core.async通道非常适合,因为您可以将websocket设置为通道上的消费者,并将其传递给所有部件,如要写入的键盘事件侦听器

它还允许您设置一个传出通道,您可以干净地连接到您的游戏状态,并将从服务器接收到的更改发送到atom中


它的要点是引入解耦,这样只要你实现某种东西,给你一个输入和输出通道,它就会工作。你可以用一个虚拟测试代替websocket实现,或者用简单的监听器和发射器代替事件和游戏状态管理,这样你就有了一个很好的接缝来隔离bugh、

事实上,我说的是服务器端,前端只是JavaScript。我认为你提出的想法仍然适用,但我不确定如何添加它们。我的要求不是真正的“阻塞”或“停车”-我基本上希望频道的信息由我的游戏循环决定,即使它是空的(表示播放器没有移动)。core.async中是否有支持此功能的内容?@quantumtremor啊,好的-如果您想将每个播放器表示为一个通道,每100毫秒只能执行一个命令,您可以使用
(a/alts!![player chan(a/timeout 100)]创建派生通道
并从游戏循环中的每个通道中取出一件物品。