天天看點

【C/S通信互動之Http篇】使用Curl與Jetty(Server)實作手機網遊Http通信架構&解決curl.h頭檔案找不到問題

之前已經分享過一篇基于Cocos2dx與伺服器使用Socket進行通信的架構,還不太熟悉的請移步到如下博文中:

<a href="http://www.himigame.com/iphone-cocos2dx/844.html" target="_blank">【C/S通信互動之Socket篇】Cocos2dx(Client)使用BSD Socket與Mina(Server)手機網遊通信架構!</a>

那麼今天Himi來分享如何在cocos2dx中使用Http來通路Server端并且擷取資料;

這裡對于Server端,Himi選用,Jetty,對于Jetty不太熟悉的可以先自行baidu~google~是個servlet的容器。類似JSP。 什麼是servlet?jsp? = =。不贅述了。大家手動好吧;

下面我們簡單書寫一個Server端(如何建立一個Jetty伺服器請看Himi  Jetty 開發系列文章)

-----------首先伺服器端--------------

這裡就ibu寫建立項目和配置項目的jar包 build path了。直接上主要代碼段:

       首先是Jetty  Server主類:(這裡Himi用的IDE 是 Eclipse)

<a href="http://blog.51cto.com/xiaominghimi/969799#">?</a>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

<code>ServletServer.java</code>

<code>import</code> <code>org.eclipse.jetty.server.Server;</code>

<code>import</code> <code>org.eclipse.jetty.servlet.ServletContextHandler;</code>

<code>import</code> <code>org.eclipse.jetty.servlet.ServletHolder;</code>

<code>import</code> <code>servlet.HServlet;</code>

<code>/**</code>

<code> </code><code>* @author Himi</code>

<code> </code><code>*/</code>

<code>public</code> <code>class</code> <code>ServletServer {</code>

<code>    </code><code>public</code> <code>static</code> <code>void</code> <code>main(String[] args) </code><code>throws</code> <code>Exception {</code>

<code>        </code><code>Server server = </code><code>new</code> <code>Server(</code><code>8080</code><code>); </code>

<code>        </code><code>ServletContextHandler context = </code><code>new</code> <code>ServletContextHandler(ServletContextHandler.SESSIONS);</code>

<code>        </code><code>context.setContextPath(</code><code>"/"</code><code>); </code>

<code>        </code><code>server.setHandler(context); </code>

<code>        </code><code>context.addServlet(</code><code>new</code> <code>ServletHolder(</code><code>new</code> <code>HServlet()), </code><code>"/himi"</code><code>); </code>

<code>        </code><code>server.start();</code>

<code>        </code><code>server.join();</code>

<code>    </code><code>}</code>

<code>}</code>

然後是我們的一個Servlet類:

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

<code>HServlet.java</code>

<code>package</code> <code>servlet;</code>

<code>import</code> <code>java.io.IOException;</code>

<code>import</code> <code>javax.servlet.ServletException;</code>

<code>import</code> <code>javax.servlet.http.HttpServlet;</code>

<code>import</code> <code>javax.servlet.http.HttpServletRequest;</code>

<code>import</code> <code>javax.servlet.http.HttpServletResponse;</code>

<code>public</code> <code>class</code> <code>HServlet </code><code>extends</code> <code>HttpServlet {</code>

<code>    </code><code>private</code> <code>static</code> <code>final</code> <code>long</code> <code>serialVersionUID = 1L; </code>

<code>    </code><code>public</code> <code>HServlet() {</code>

<code>    </code><code>} </code>

<code>    </code><code>protected</code> <code>void</code> <code>doGet(HttpServletRequest request, HttpServletResponse response) </code><code>throws</code> <code>ServletException, IOException {</code>

<code>        </code><code>System.out.println(</code><code>"~~~~有一個Clinet通路!~~~~"</code><code>);</code>

<code>        </code><code>//擷取http Client端對應的兩個字段的資料</code>

<code>        </code><code>String name = request.getParameter(</code><code>"name"</code><code>);</code>

<code>        </code><code>String password = request.getParameter(</code><code>"password"</code><code>);</code>

<code>        </code><code>//設定字元編碼</code>

<code>        </code><code>response.setCharacterEncoding(</code><code>"UTF-8"</code><code>);</code>

<code>        </code><code>response.setContentType(</code><code>"text/html"</code><code>);</code>

<code>        </code><code>response.setStatus(HttpServletResponse.SC_OK);</code>

<code>        </code><code>response.getWriter().println(</code><code>"Server say: 測試中文:session="</code> <code>+ request.getSession(</code><code>true</code><code>).getId()); </code>

<code>        </code><code>if</code><code>(name!=</code><code>null</code><code>) {</code>

<code>            </code><code>response.getWriter().println(</code><code>"Server say:名字:"</code><code>+name);</code>

<code>            </code><code>System.out.println(</code><code>"Client say: name="</code><code>+name);</code>

<code>        </code><code>}</code>

<code>        </code><code>if</code><code>(password!=</code><code>null</code><code>) {</code>

<code>            </code><code>response.getWriter().println(</code><code>"Server say:密碼:"</code><code>+password);</code>

<code>            </code><code>System.out.println(</code><code>"Client say: password="</code><code>+password);</code>

我們的Servlet裡,就是得到http clinet端傳過來的資料傳回回去。中間簡單寫給用戶端一些簡單字元串~

      OK,啟動我們的Jetty伺服器,右鍵ServletServer.java run,觀察控制台:

<code>2012-05-25 16:43:04.767:INFO:oejs.Server:jetty-8.1.3.v20120416</code>

<code>2012-05-25 16:43:05.110:INFO:oejs.AbstractConnector:Started [email protected]:8080</code>

出現如上,表示你的Jetty Server啟動成功;OK。然後設計用戶端代碼;

-----------然後cocos2dx Clinet端--------------

首先建立一個cocos2dx項目,這個不多說。然後在預設的HelloWorldScene.cpp 初始化函數替換如下代碼:

44

45

46

47

<code>bool</code> <code>HelloWorld::init()</code>

<code>{</code>

<code>/*</code>

<code> </code><code>*@author By Himi</code>

<code>    </code><code>//////////////////////////////</code>

<code>    </code><code>// 1. super init first</code>

<code>    </code><code>if</code> <code>( !CCLayer::init() )</code>

<code>    </code><code>{</code>

<code>        </code><code>return</code> <code>false</code><code>;</code>

<code>    </code><code>CCLabelTTF* pLabel = CCLabelTTF::labelWithString(</code><code>"Hello World"</code><code>, </code><code>"Thonburi"</code><code>, 34);</code>

<code>    </code><code>CCSize size = CCDirector::sharedDirector()-&gt;getWinSize();</code>

<code>    </code><code>pLabel-&gt;setPosition( ccp(size.width / 2, size.height - 20) );</code>

<code>    </code><code>this</code><code>-&gt;addChild(pLabel, 1);</code>

<code>    </code><code>CURL *curl;</code>

<code>    </code><code>CURLcode res;</code>

<code>    </code><code>char</code> <code>buffer[10];</code>

<code>    </code><code>curl = curl_easy_init();</code>

<code>    </code><code>if</code> <code>(curl)</code>

<code>//        curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:8080/himi");</code>

<code>        </code><code>curl_easy_setopt(curl, CURLOPT_URL, </code><code>"http://127.0.0.1:8080/himi?name=xiaoming&amp;password=李華明"</code><code>);</code>

<code>        </code><code>res = curl_easy_perform(curl);</code>

<code>        </code><code>/* always cleanup */</code>

<code>        </code><code>curl_easy_cleanup(curl);</code>

<code>        </code><code>if</code> <code>(res == 0)</code>

<code>        </code><code>{</code>

<code>            </code><code>pLabel-&gt;setString(</code><code>"0 response"</code><code>);</code>

<code>        </code><code>else</code>

<code>            </code><code>sprintf</code><code>(buffer,</code><code>"code: %i"</code><code>,res);</code>

<code>            </code><code>pLabel-&gt;setString(buffer);</code>

<code>    </code><code>else</code>

<code>        </code><code>pLabel-&gt;setString(</code><code>"no curl"</code><code>);</code>

<code>    </code><code>return</code> <code>true</code><code>;</code>

OK,然後我們導入 curl.h頭檔案:

<code>#include "curl/curl.h"</code>

還沒完,這時候提示我們找不到這個頭檔案,OK,繼續操作兩步如下:

1.   加入 libcurl.a 檔案:(此檔案預設在cocos2dx引擎包下的cocos2dx/platform/third_party/ios/libraries檔案夾下)

<a href="http://www.himigame.com/wp-content/uploads/2012/05/18.png"></a>

别着急這時候還會提示頭檔案找不到;

在xcode中點選你的cocos2dx項目,然後選擇你項目的 targets,然後在Build Settings中找到 Search Paths:

輕按兩下你的 Library Search Paths 觀察:如下圖:

<a href="http://www.himigame.com/wp-content/uploads/2012/05/25.png"></a>

下面那個"$...../third_party/ios/libraries"路徑是你第一步添加lib curl.a的時候預設添加的。這個我們不要修改;但是請輕按兩下這個路徑然後copy下來;

我們需要修改的是此屬性的上一個屬性,Header Search Paths;

輕按兩下Header Search Paths屬性後面的連接配接,然後點選“+”号添加一個路徑,這個路徑就是剛才你copy的路徑,但是粘貼後還要将此路徑設定到上一個檔案夾的路徑;這麼說有點繞,其實就是如下:

假設你之前copy的路徑是  "$...../third_party/ios/libraries"

   那麼你在這裡粘貼的時候路徑應該是: "$...../third_party/ios"

OK,Himi這裡的路徑也截圖給大家一張便于對比:

<a href="http://www.himigame.com/wp-content/uploads/2012/05/31.png"></a>

OK,如果以上步驟都操作正常那麼編譯将沒有任何問題;

編譯成功後,command+R運作項目,觀察xcode控制台列印,以及伺服器端列印:正常情況下應該如下:

<a href="http://www.himigame.com/wp-content/uploads/2012/05/4.png"></a>

OK,一切正常;

       注意:用腳本建立的工程,預設是不加libcurl的,大家編譯到其他平台的時候要修改makefile檔案将其添加進去;(具體可以參考tests裡面的makefile ) 

       提醒 :這裡用戶端與伺服器隻是簡單的http互動,沒有更細節的處理,例如 Client端通路應該另起一個線程,互動的時候資料要有一定的協定規範等等這些在介紹Socket的時候都有說過了,這裡就不多說了; 

本文轉自 xiaominghimi 51CTO部落格,原文連結:http://blog.51cto.com/xiaominghimi/969799,如需轉載請自行聯系原作者