码迷,mamicode.com
首页 > 其他好文 > 详细

cocos2dx获取网络时间(一)

时间:2014-12-27 20:23:53      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:

  今天在公司的cocos2dx项目中遇到一个需求,需要获取网络时间和系统时间对比,目的是防止用户更改系统时间进行某些非法操作 。

  那么cocos2dx怎么来获取网络时间呢 ?我整理的思路如下:

  (1)由一个web api可以返回当前的网络时间

  (2)cocos2dx通过http请求该api获取数据到本地

  (3)cocos2dx解析数据得到当前的网络时间

一:首先就需要一个web接口来提供网络时间的数据,我在这里自己搭建一个WCF服务返回需要的数据。

  新建WCF服务应用程序 , 项目命名为NetTimeService,将解决方案命名为NetTime:

技术分享

  在解决方案资源管理器新建WCF服务:

技术分享

  由于我们仅需要通过HTTP GET请求数据,故使用webHttpBinding即可。Web.config配置如下:

  

技术分享
 1 <system.serviceModel>
 2     <services>
 3       <service name="NetTimeService.NetTime">
 4         <endpoint binding="webHttpBinding" behaviorConfiguration="webGet" contract="NetTimeService.INetTime"/>
 5       </service>
 6     </services>
 7     <behaviors>
 8       <endpointBehaviors>
 9         <behavior name="webGet">
10           <webHttp/>
11         </behavior>
12       </endpointBehaviors>
13       <serviceBehaviors>
14         <behavior> 
15           <serviceMetadata httpGetEnabled="false"/>
16           <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 -->
17           <serviceDebug includeExceptionDetailInFaults="false"/>
18         </behavior>
19       </serviceBehaviors>
20     </behaviors>
21     <serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
22   </system.serviceModel>
View Code

  WCF加入了对URI模板(UriTemplate)和JSON(WebMessageFormat.Json)的支持,使用WebGet对需要访问的方法WebDateTime()进行标记,并使用Json格式返回数据:

技术分享
 1 namespace NetTimeService
 2 {
 3     // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“INetTime”。
 4     [ServiceContract]
 5     public interface INetTime
 6     {
 7         [OperationContract]
 8         [WebGet(UriTemplate = "/Time", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
 9         Time WebDateTime();
10     }
11 }
View Code

  我们需要获取的网络时间数据包括年,月,日,小时,分和秒,定义Time类:

  

技术分享
 1 namespace NetTimeService
 2 {
 3     [DataContractAttribute]
 4     public class Time
 5     {
 6         [DataMemberAttribute]
 7         public int Year { get; set; }
 8         [DataMemberAttribute]
 9         public int Month { get; set; }
10         [DataMemberAttribute]
11         public int Day { get; set; }
12         [DataMemberAttribute]
13         public int Hour { get; set; }
14         [DataMemberAttribute]
15         public int Minute { get; set; }
16         [DataMemberAttribute]
17         public int Second { get; set; }
18         public Time(DateTime dt)
19         {
20             this.Year = dt.Year;
21             this.Month = dt.Month;
22             this.Day = dt.Day;
23             this.Hour = dt.Hour;
24             this.Minute = dt.Minute;
25             this.Second = dt.Second;
26         }
27     }
28 }
View Code

  WebDateTime()方法的实现如下:

  

技术分享
 1 namespace NetTimeService
 2 {
 3     // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“NetTime”。
 4     // 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 NetTime.svc 或 NetTime.svc.cs,然后开始调试。
 5     public class NetTime : INetTime
 6     {
 7         public Time WebDateTime()
 8         {
 9             Time dt = new Time(DateTime.Now);
10             return dt;
11         }
12     }
13 }
View Code

  使用浏览器查看NetTime.svc,出现如下页面说明服务配置成功:

技术分享

 在浏览器地址栏输入http://localhost:23244/NetTime.svc/Time 便可以得到我们需要的json数据:

 技术分享

二:接下来便通过cocos2dx http访问服务来获取数据

  cocos2dx使用CCHttpClient对CURL进行封装,采用http的方式传输数据。

  在NetTime解决方案下新建cocos2dx项目,命名为NetTimeTest。

  使用HttpClient需要导入头文件:

   

#include "cocos-ext.h"
USING_NS_CC_EXT;

  在HelloWorldScene.cpp的init()方法中添加如下代码:

  

技术分享
1 CCHttpRequest * request = new CCHttpRequest();
2 request->setUrl("http://localhost:23244/NetTime.svc/Time");
3 request->setRequestType(CCHttpRequest::kHttpGet);
4 request->setTag("WebTime");
5 request->setResponseCallback(this, httpresponse_selector(HelloWorld::onHttpComplete));
6 CCHttpClient::getInstance()->send(request);
View Code

  在onHttpComplete回调方法中:

  

技术分享
 1 void HelloWorld::onHttpComplete(CCHttpClient * sender, CCHttpResponse * response)
 2 {
 3     CCHttpClient::getInstance()->release();
 4     if (!response)
 5         return;
 6     if (0 != strlen(response->getHttpRequest()->getTag()))
 7     {
 8         CCLog("%s completed", response->getHttpRequest()->getTag());
 9     }
10     int statusCode = response->getResponseCode();
11     char statusString[64] = {};
12     sprintf(statusString, "HTTP Status: %d, tag = %s", statusCode, response->getHttpRequest()->getTag());
13     CCLog("%s", statusString);
14     if (!response->isSucceed())
15     {
16         CCLog("response failed");
17         CCLog("error buffer:%s", response->getErrorBuffer());
18         return;
19 
20     }
21     std::vector<char> * buffer = response->getResponseData();
22     std::string str;
23     for (unsigned i = 0; i < buffer->size(); i++)
24     {
25         char a = (*buffer)[i];
26         str.append(1, a);
27     }
28     CCLog("%s", str.c_str());
29 }
View Code

  运行cocos2dx项目,可以在输出控制台看到 成功的通过cocos2dx获取到了网络时间:

技术分享

三:但是得到的数据是Json格式,并不能直接在项目里使用,就需要进行json数据的解析:

  我在这里使用的是rapidjson,包含在cocostudio工程中。

  同样先导入头文件:

  

#include "CocoStudio\Json\rapidjson\rapidjson.h"
using namespace rapidjson;

  定义readJson方法解析json数据:

技术分享
 1 void HelloWorld::readJson(string jsonStr)
 2 {
 3     Document doc;
 4     doc.Parse<0>(jsonStr.c_str());
 5     if (!doc.IsObject())
 6         return;
 7     if (doc.HasMember("Year") && doc.HasMember("Month") && doc.HasMember("Day") && doc.HasMember("Hour") && doc.HasMember("Minute") && doc.HasMember("Second"))
 8     {
 9         const Value &pYear = doc["Year"];
10         int    year = pYear.GetInt();
11         const Value &pMonth = doc["Month"];
12         int month = pMonth.GetInt();
13         const Value &pDay = doc["Day"];
14         int day = pDay.GetInt();
15         const Value &pHour = doc["Hour"];
16         int hour = pHour.GetInt();
17         const Value &pMinute = doc["Minute"];
18         int minute = pMinute.GetInt();
19         const Value &pSecond = doc["Second"];
20         int second = pSecond.GetInt();
21         char timeStr[50];
22         sprintf(timeStr, "NetTime  %d-%d-%d %d:%d:%d",
23             year, month, day,hour, minute, second);
24         CCLabelTTF *timeLabel = CCLabelTTF::create(timeStr, "Arial", 18);
25         timeLabel->setPosition(ccp(240, 50));
26         this->addChild(timeLabel);
27     }
28 }
View Code

  在onHttpComplete方法最后添加对readJson方法的调用:

  技术分享

  运行项目:

  技术分享

  Demo下载 :NetTime.zip

  本文在cocos2dx中使用的方法参考了他人博客:

  Cocos2d-x笔记 CCHttpCleint网络请求 

  cocos2dx 读取json及解析 

  但本文主要提供了一种解决问题的思路供大家参考。 如果你对cocos2dx获取网络时间有更好的解决方案,欢迎提出和大家一起讨论。

  最后的问题,如果要在另外的项目中使用上面的方法,那么应该怎么对这些方法进行封装呢 ?在下一篇文章里我会和大家揭晓。

cocos2dx获取网络时间(一)

标签:

原文地址:http://www.cnblogs.com/lhyEmpty/p/4188678.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!