PHP游戏服务器之GlobalData组件的运用

本文介绍了一种使用PHP和WorkerMan开发的游戏服务器设计方案。通过GlobalData组件实现进程间共享数据,确保用户间的公共数据同步。文章提供了具体的代码示例,并讨论了性能影响及优化建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        众所周之,服务器的设计永远不能依赖于单进程/单线程,由于PHP本质上是不支持多线程的,所以在开发过程中,只能把不同的逻辑或者用户分发到不同的进程之间进行处理(这是由系统自己调用分发的)。由此可知道在游戏中用户之间必须共享一些特定的公共数据,由于PHP进程之间不能够直接调用数据,所以就需要一个共公的数据库或者内存空间进行保存,因我的服务器采用的是WorkerMan进行开发的,所以用到的公共组件可以是GlobalData或者Redis组件,它是实质就是公有数据库服务。此处采用的是GlobalData组件。以下是实现代码:

 

class Events
{
    private static $globalClient;
    /**
     * WORKER端启动的时候调用,用于初始化全局数据
     * @param $worker
     */
    public static function onWorkerStart($worker){
        //连接进程共享数据服务器
        self::$globalClient = new GlobalData\Client("127.0.0.1:2207");
        //创建当前服务器
        $server = new GameServer();
        //保存共享数据,本函数只执行一次
        self::$globalClient->add('server', $server);
    }
    /**
     * 当客户端连接时触发
     * 如果业务不需此回调可以删除onConnect
     * 
     * @param int $client_id 连接id
     */
    public static function onConnect($client_id)
    {
        //检查是否有更新,返回更新结果
        //echo $client_id."\n";
        echo "connect:".Gateway::getAllClientCount()."\n";
    }
    
   /**
    * 当客户端发来消息时触发
    * @param int $client_id 连接id
    * @param mixed $message 具体消息
    */
   public static function onMessage($client_id, $message)
   {

       do{
           //获取服务器,当前服务器和保存的服务器环境
           $server = self::$globalClient->server;
           $oldServer = self::$globalClient->server;

           //开始处理客户端请求,内部调用响应函数返回客户端
           $t=$server->processClientRequest($client_id, $message);
       }while(!self::$globalClient->cas('server', $oldServer, $server));

       if($t){
           for($i=0;$i<count($t);$i++){
               $server->processServerResponse($t[$i][0],$t[$i][1],$t[$i][2],$t[$i][3],$t[$i][4]);
           }
       }
   }
   
   /**
    * 当用户断开连接时触发
    * @param int $client_id 连接id
    */
   public static function onClose($client_id)
   {

       echo "exit!\n";
       //当用户断开连接时
       //获取服务器,当前服务器和保存的服务器环境
       do{
           //获取服务器,当前服务器和保存的服务器环境
           $server = self::$globalClient->server;
           $oldServer = self::$globalClient->server;

           $server->disconnect($client_id);
       }while(!self::$globalClient->cas('server', $oldServer, $server));

   }
}

此处就是创建了一个GlobalData数据服务,里面存储的是游戏中公用的数据,封装在GameServer里面,每次都可通过GameServer进行调用。需要注意的就是因此方法的本质是IO阻塞式的,是一个原子操作,会影响到服务器的一定性能,在游戏中如果要达到正常通信,进行游戏分区是不很不错的方法的。

 

官方文档地址:http://doc.workerman.net/315189

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值