PHP游戏服务器,多个TCP客户端?

时间:2010-11-23 23:31:40

标签: php tcp websocket

我正在制作基于网络浏览器的多人游戏。鉴于其实时性,我已经确定websockets是处理通信的最佳方式。客户端使用HTML5画布渲染游戏和websockets以与主机通信。

我选择使用PHP来托管游戏,因为它似乎是托管服务提供商的首选。我之前没有使用PHP,但是在Java中使用websockets做了类似的事情,但是很多地依赖于多线程。

我一直在寻找有关多个客户端的php套接字的一些教程;但是他们中的大多数都会为每个客户端分配新流程。由于我将有一个不断运行的游戏循环,我不认为这是合适的。

我想要实现的是在连接时为每个客户端分配端口,侦听新客户端,与当前客户端列表交换数据以及一起运行游戏循环的方法。

我需要帮助的地方是:

  • 如何查找端口并为新客户端分配端口,通知客户端该端口,并在断开连接时进行清理。
  • 如何执行上述操作以及所有其他套接字事务,而不会阻塞游戏循环。接受来自部分块的客户端的消息并且只对完整的消息起作用是可以接受的。

任何人都可以就如何实现这些目标向我提供一些技术建议吗? 我不认为这对PHP的要求太多了,但如果我错了就纠正我!

我想要实现服务器端的一些伪代码。这些功能都不应该阻止:     数组客户端;

while(gamerunning)
{
    CheckForNewClients();
    GetStatusFromClients();
    DoGameUpdate();
    SendGameStateToClients();
}

[更新] 对于任何感兴趣的人,我创建了一个支持Web套接字的专用应用程序(特别是使用Java和'TooTallNates'的Web套接字库),而不是实际的Web服务,因为它似乎更有意义,尽管从大多数Web浏览器开始,它似乎已经挂起了web由于安全问题,垃圾箱中的插座。

2 个答案:

答案 0 :(得分:7)

您确实需要运行PHP守护程序才能有效地执行此操作(并且需要PHP 5.3)。我写了一篇关于使用PHP for daemon processes的完整概述。无论你选择什么,我建议你使用基于事件的运行循环系统。

我设计了一个名为LooPHP的基本RunLoop库,它可能会有所帮助,特别是如果您要处理*_select。我非常乐意回答你的任何问题。

编辑:

在基于事件的系统中,您不仅仅是while一个命令列表,您对一个监听器做出反应。例如......

而不是:

while( 1 ) {
    ... /* listen, react */
} /* repeat */

通过注册监听器(套接字和其他异步事件生成器)来运行循环工作

class ReactClass { ... }

$loop = new LooPHP_EventLoop( new ReactClass );

//add one time event
$loop->addEvent( function() {
    print "This event was called 0.5 second after being added\n";
}, 0.5 /* in seconds */ );

//this creates a repeating event, this is called right away and repeats
$add_event = function() use ( $loop, &$add_event ) {
    print "This event is REPEATEDLY called 0.1 every second\n";
    $loop->addEvent( $add_event, 0.1 );
};
$add_event();

//start the loop processing, no events are processed until this is done
$loop->run(); //php doesn't leave this call until the daemon is done
exit(0); //cleanly exit

以上情况是一个非常简单的1源EventLoop和一个手动添加定时功能(甚至可以在调用ReactClass时添加这些功能)。

在我正在工作的应用程序中,我需要将异步事件提供到后端(通过套接字),然后需要能够从原始事件调用函数任意偏移量(用于超时客户端等) )。

如果您想了解更多示例,可以在github找到它们。

我希望你觉得这很有用。

答案 1 :(得分:5)

我不建议将PHP用于此类应用程序。 PHP没有正式支持多线程,并且在未定义的时间段内运行PHP脚本(如服务器)并不是真正的广告功能。

当然你可以尝试创造历史:)

(如果我弄错了,请纠正我)