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

        众所周之,服务器的设计永远不能依赖于单进程/单线程,由于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

发布了23 篇原创文章 · 获赞 25 · 访问量 4万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 游动-白 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览