RakNet(59)学习 -- PHP Directory Server(目录服务器)

来源:互联网 发布:集换式卡牌手游 知乎 编辑:程序博客网 时间:2024/05/20 19:15

PHP 目录服务器概述

 

使用共享的Web主机给出游戏列表

       Lightweight数据库插件功能强大,但是它要求一个一台专用的服务器运行RakNet实例。在有些情况下,这个要求无法满足,并且运行专用服务器额负担也是不可取的。对于这些情况,RakNet提供了一个DirectoryServer.php,它可以再Sample\PHPDirecotory目录下找到。

       设置web服务器,仅仅需要将Samples\PHPDirectoryServer\Directory.php上传到你的PHPweb主机即可(webhost可以是任何标准的web服务器)。转到你新上传的webpage,点击显示按钮,输入密码和其他的想要的设置参数。

       C++代码更加复杂。首先,你需要定义一个TCPInterface的实例,并且启动该实例。这是通常的TCP通信必备。

       TCPInterface tcp;

       tcp.Start(0, 64);

       第二,还需要一个HTTPConnection实例,它用于通过TCPInterface实例与webpages进行通信。

       HTTPConnection httpConnection(tcp, "jenkinssoftware.com");

       第三,你需要定义一个PHPDirectoryServer实例。它用于解析和与指定的DirectoryServer.php通信。

       PHPDirectoryServer phpDirectoryServer(httpConnection, "/raknet/DirectoryServer.php");

       转到http://www.jenkinssoftware.com/raknet/DirectoryServer.php可以实际看一看页面效果。

       然后你可以设置列,上传你的表或下载已经存在的表:

      

       // 使用columnname / value设置域值

       phpDirectoryServer.SetField("beehive","inthewater");

 

       // 上传前面设置的域,要用到游戏名称,游戏端口,和密码

       phpDirectoryServer.UploadTable(50, "Game name", 1234, "");

 

       // 下载上传的服务器

       phpDirectoryServer.DownloadTable("");

      

       更新系统,应该从TCPInterface向两个接口传递数据包,并且要调用Update()TCP数据报没有包含一个完整的webpage响应,webpage可能包含错误代码,来自webpage的信息不全是与我们的服务器相关的使得事情变得比较复杂。例子详细说明了如何处理,如下的代码是一个简要的摘录:

       Packet *packet = tcp.Receive();

       if(packet)

       {

              // 在这个例子中,这一行不是必须的,但是如果我们正在使用TCPInterface,我们想要确保我们仅仅给它一个消息表明我们我们的本条连接。

              if (packet->systemAddress==httpConnection.GetServerAddress())

              {

                     // 从一个web服务器一条请求可能返回多个数据报。当最后的数据报达到时, ProcessFinalTCPPacket会返回真

                     if (httpConnection.ProcessFinalTCPPacket(packet))

                     {

                            int code;

                            RakNet::RakString data;

                            /// 检查请求已经处理,没有错误代码

                            if (httpConnection.HasBadResponse(&code, &data)==false)

                           {

                                   // 好的响应,让PHPDirectoryServer类处理该数据

                                   // 如果resultCode不是空字符串,那么我们得到了一些东西而非表

                                   // (例如删除行成功提示,或消息仅仅是HTTP的并不是本类的数据).

                                   HTTPReadResult readResult = phpDirectoryServer.ProcessHTTPRead(httpResult);

                                   if (readResult==HTTP_RESULT_GOT_TABLE)

                                   {

                                          /// 获得了一个内部存储的表,打印出来。

                                          char out[10000];

                                          const DataStructures::Table *games = phpDirectoryServer.GetLastDownloadedTable();

                                          games->PrintColumnHeaders(out,sizeof(out),',');

                                          printf("COLUMNS: %s\n", out);

 

                                          // 打印表的每一行

                                          for (unsigned i=0; i < games->GetRowCount(); i++)

                                          {

                                                 games->PrintRow(out,sizeof(out),',',true, games->GetRowByIndex(i,NULL));

                                                 printf("ROW %i: %s\n", i+1, out);

                                          }

                                   }

                            }

                     }

              } 

              // 释放数据报

              tcp.DeallocatePacket(packet);

       }

       httpConnection.Update();

       phpDirectoryServer.Update();

 

       某些列被保存,给你返回一个查询。这些列名字不允许用于终端用户,如果参数使用会发生assert(断言)

       // 带有这个头的列包含了游戏的名字,传递给UploadTable()

       static const char *GAME_NAME_COMMAND="__GAME_NAME";

       // 带有这个头的列包含了游戏的端口,传递给UploadTable()

       static const char *GAME_PORT_COMMAND="__GAME_PORT";

       // PHP服务器返回,表明了这行最后更新的时间。

       static const char *LAST_UPDATE_COMMAND="__SEC_AFTER_EPOCH_SINCE_LAST_UPDATE";

       // 删除一行的命令

       static const char *DELETEME_COMMAND="__DELETE_ROW";

       // 传递给PHP服务器,它是作为密码

       static const char *GAME_PASSWORD_COMMAND="__PHP_DIRECTORY_SERVER_PASSWORD";

       // 这一列传递给PHP服务器,作为在自动推出之前多长时间列出这个服务器。

       static const char *GAME_TIMEOUT_COMMAND="__GAME_LISTING_TIMEOUT";

        

       __SYSTEM_ADDRESS参数被返回表明外部的一个IP用于上传webpage

       注意由于技术限制,在同一个时间仅仅允许一个上传。如果你的服务器仅仅管理一个游戏,那么这个限制不是问题。当一个上传正在进行,如果调用了PHPDirectoryServer::UploadTable()方法会覆盖掉这前一个上传。当HTTPConnectionBusy()返回false时可以执行另外一个上传过程。

0 0
原创粉丝点击