我对 haskell 网络(以及一般的点对点通信)相当陌生,并且正在寻找一种玩家对玩家的网络刽子手游戏,类似于流行的“与朋友一起玩”。在学习了包括 haskell.org 的“实现聊天服务器”在内的一些教程之后,我能够成功地创建一个服务器并将套接字连接到套接字,然后将消息弹回第四次。
我还有一个刽子手客户端,当给定预先确定的输入时,它会按预期播放。
但是,我在连接的客户端之间遇到了排序事件的问题。因为对套接字通道的读取和写入发生在不同的线程上(由于 readChan 和 writeChan 的阻塞性质),我不确定如何在远程终端之间对操作进行排序。我知道我想要什么,只是不知道如何到达那里:
- 一旦第二个用户连接,调用“发送”功能,提示他们输入第一个玩家的输入词
- 玩家 1 通过“recieve”函数接收到这个词,如果它不是命令关键字(加入、退出、结果),则使用提供的词运行刽子手游戏。与此同时,玩家 2 的屏幕被阻塞,等待玩家 1 完成。
- 玩家 1 结束。他的结果被记录下来,然后为他调用“发送”函数,提示他输入以玩游戏。
- 重复 2-3 直到玩家退出。
我已经通过几种方式解决了这个问题。我比较成功的方法之一是通过阻塞信号量。我曾想过在轮到“控制”播放器时使用 MVar。它在第一回合正确运行,但此后退化为乱码。通道内信号量的概念(本质上是一个 MVar,因为它也被阻塞了)真的让我很头疼。由于它确实阻塞,因此也很难调试。
我对信号量的了解有点动摇。我这样做的方式是否有意义?
该代码可以在 bitbucket 存储库中找到。以下是获取正确代码/分支所需的步骤:
git clone git@bitbucket.org:ndisidore/haskell-hangman.git
git checkout block-sem
或在这里在线查看。
跑步:runhaskell NetInterface.hs
这将创建一个侦听端口 3468 的套接字
要作为客户端/播放器连接,请打开一个单独的终端并运行“telnet localhost 3468”。这需要进行两次,每个玩家一次。
提前致谢。