客戶端API

使用pomelo做服務端開發時,無論什麼客戶端,只要能遵循與服務端的線上協議,就能夠與服務端建立通信。pomelo內建提供的sioconnector和hybridconnector都定義了自己的協議格式,其中sioconnector用於socket.io的通信,hybridconnector則用來處理websocket和tcp的連接通信。爲了方便客戶端的開發,pomelo提供了部分平臺的客戶端SDK,這裏主要會介紹一下用於Web端的JavaScript的SDK以及基於C語言的libpomelo的使用。

Web端JavaScript開發庫

對於瀏覽器來說,HTML5中已經支持了websocket,因此使用支持websocket的瀏覽器可以直接與服務端的hybridconnector建立通信。而對於比較舊的瀏覽器來說,還沒有支持websocket的,可以使用基於socket.io的方式進行與服務端建立連接。因此,對於Web端,pomelo提供了兩套開發庫,分別適用於支持websocket的瀏覽器和不支持websocket的瀏覽器,這兩套開發庫的鏈接如下,適用於socket.io的pomelo-jsclient-socket.io以及適用於websocket的pomelo-jsclient-websocket

socket.io的客戶端開發庫

對於使用socket.io的客戶端SDK來說,其依賴socket.io-client, 由於這個庫在使用component進行管理時有bug,因此在使用的時候,是直接引用其提供的js文件,具體引用的js文件爲socket.io-client.js。對於pomelo-jsclient-socket.io來說,同樣也是直接使用引用其js文件,也即是pomelo-client.js。在直接引用這兩個文件後即可使用pomelo的調用了。

websocket的客戶端開發庫

對於使用websocket的客戶端SDK來說,使用了component進行管理,因此只需要配置一個component.json文件,裏面配置相應的依賴,然後運行

$ component install
$ component build

component會自動尋找依賴,完成客戶端js的打包。用戶只需要引用編譯後的build.js即可,然後就可以使用pomelo的調用了。關於component的使用,請參考component的wiki。我們的例子chatofpomelo-websocket,這裏就是使用了component來管理前端js的,可以作爲用戶使用的一個參考。

#### web端API簡介

無論是socket.io的還是websocket的,都提供了統一的API,下面對這些API進行簡單的介紹。

  • pomelo.init(params, cb)

這是往往是客戶端的第一次調用,params中應該指出要連接的服務器的ip和端口號,cb會在連接成功後進行回調;

  • pomelo.request(route, msg, cb)

請求服務,route爲服務端的路由,格式爲"..", msg爲請求的內容,cb會響應回來後的回調;

  • pomelo.notify(route, msg)

發送notify,不需要服務器迴響應的,因此沒有對響應的回調,其他參數含義同request;

  • pomelo.on(route, cb)

這個是從EventEmmiter繼承過來的方法,用來對服務端的推送作出響應的。route會用戶自定義的,格式一般爲"onXXX";

  • pomelo.disconnect()

這個是pomelo主動斷開連接的方法。

libpomelo

libpomelo 是 pomelo 的 c 客戶端,支持pomelo 0.3版本以後的協議

依賴

  • libuv 跨平臺開發庫,主要使用了網絡I/O和線程
  • jansson c 的 json 解析庫

使用

創建客戶端實例

// create a client instance.
pc_client_t *client = pc_client_new();

添加事件監聽

// add some event callback.
pc_add_listener(client, "onHey", on_hey);
pc_add_listener(client, PC_EVENT_DISCONNECT, on_close);

監聽器的定義

// disconnect event callback.
void on_close(pc_client_t *client, const char *event, void *data) {
  printf("client closed: %d.\n", client->state);
}

連接到服務器

struct sockaddr_in address;

memset(&address, 0, sizeof(struct sockaddr_in));
address.sin_family = AF_INET;
address.sin_port = htons(port);
address.sin_addr.s_addr = inet_addr(ip);

// try to connect to server.
if(pc_client_connect(client, &address)) {
  printf("fail to connect server.\n");
  pc_client_destroy(client);
  return 1;
}

發起一個 notify 請求

// notified callback
void on_notified(pc_notify_t *req, int status) {
  if(status == -1) {
    printf("Fail to send notify to server.\n");
  } else {
    printf("Notify finished.\n");
  }

  // release resources
  json_t *msg = req->msg;
  json_decref(msg);
  pc_notify_destroy(req);
}

// send a notify
void do_notify(pc_client_t *client) {
  // compose notify.
  const char *route = "connector.helloHandler.hello";
  json_t *msg = json_object();
  json_t *json_str = json_string("hello");
  json_object_set(msg, "msg", json_str);
  // decref json string
  json_decref(json_str);

  pc_notify_t *notify = pc_notify_new();
  pc_notify(client, notify, route, msg, on_notified);
}

發起一個 requst 請求

// request callback
void on_request_cb(pc_request_t *req, int status, json_t *resp) {
  if(status == -1) {
    printf("Fail to send request to server.\n");
  } else if(status == 0) {
    char *json_str = json_dumps(resp, 0);
    if(json_str != NULL) {
      printf("server response: %s\n", json_str);
      free(json_str);
    }
  }

  // release relative resource with pc_request_t
  json_t *msg = req->msg;
  pc_client_t *client = req->client;
  json_decref(msg);
  pc_request_destroy(req);

  // stop client
  pc_client_stop(client);
}

// send a request
void do_request(pc_client_t *client) {
  // compose request
  const char *route = "connector.helloHandler.hi";
  json_t *msg = json_object();
  json_t *str = json_string("hi~");
  json_object_set(msg, "msg", str);
  // decref for json object
  json_decref(str);

  pc_request_t *request = pc_request_new();
  pc_request(client, request, route, msg, on_request_cb);
}

API 接口

  • 創建一個新的pomelo client實例
pc_client_t *pc_client_new();
  • 停止客戶端的連接
    該接口適合於在libuv子線程中調用,然後在主線程中,通過 pc_client_join來wait子線程退出
void pc_client_stop(pc_client_t *client);
  • 銷燬客戶端的連接
void pc_client_destroy(pc_client_t *client);
  • 主線程中調用等待子線程的退出
int pc_client_join(pc_client_t *client);
  • 創建一個request請求實例
pc_request_t *pc_request_new();
  • 銷燬一個request請求實例
void pc_request_destroy(pc_request_t *req);
  • 連接到服務器,在連接過程中會創建子線程用於處理網絡I/O
int pc_client_connect(pc_client_t *client, struct sockaddr_in *addr);
  • 銷燬pc_connect_t類型的實例
void pc_connect_req_destroy(pc_connect_t *conn_req);
  • 發起一個request請求
int pc_request(pc_client_t *client, pc_request_t *req, const char *route,
               json_t *msg, pc_request_cb cb);
  • 創建一個notify請求實例
pc_notify_t *pc_notify_new();
  • 銷燬一個notify請求實例
void pc_notify_destroy(pc_notify_t *req);
  • 發起一個notify請求
int pc_notify(pc_client_t *client, pc_notify_t *req, const char *route,
              json_t *msg, pc_notify_cb cb);
  • 添加一個事件監聽
int pc_add_listener(pc_client_t *client, const char *event,
                    pc_event_cb event_cb);
  • 刪除一個事件監聽
void pc_remove_listener(pc_client_t *client, const char *event,
                    pc_event_cb event_cb);
  • 觸發一個事件監聽
void pc_emit_event(pc_client_t *client, const char *event, void *data);

編譯

前提條件

下載 gyp
gyp 其實是一個python寫的腳本,並不需要安裝,只需要下載下來,可以執行gyp裏面的腳本就行

Mac 環境

./pomelo_gyp
xcodebuild -project pomelo.xcodeproj

IOS 環境

./pomelo_gyp -DTO=ios
./build_ios

IOS 模擬器

./pomelo_gyp -DTO=ios
./build_iossim

Linux 環境

./pomelo_gyp
make

Windows 環境

在libpomelo項目跟目錄下
打開git bash,敲入

mkdir -p build
git clone https://github.com/martine/gyp.git build/gyp

之後,打開windows cmd命令行窗口,並且cd切換目錄到libpomelo跟目錄下面,敲入

build\gyp\gyp.bat --depth=. pomelo.gyp -Dlibrary=static_library -DTO=pc 

之後就會生成pomelo.sln,使用visual studio打開即可進行編譯

Android 環境

開發前提條件:
windows:

  • 安裝 Cygwin with make (select make package from the list during the install).
  • android adt eclipse 這個只要下載最新的 android sdk 裏面就有一個配置好環境的 eclipse

環境搭建:
1: 新建一個 android 工程,比如新建一個 test 的 工程,建完之後如圖:
test工程

2: 然後在項目根目錄下面,新建一個 jni 文件夾
然後裏面添加一個 Android.mk 文件
Android.mk 裏面敲入

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := game_shared

LOCAL_MODULE_FILENAME := libgame               

LOCAL_WHOLE_STATIC_LIBRARIES := pomelo_static
            
include $(BUILD_SHARED_LIBRARY)

LOCAL_CFLAGS    := -D__ANDROID__ 

$(call import-module,libpomelo) 

這樣子就表示將在 android 中使用 libpomelo 編譯而來的 .so 庫

3: 然後在項目目錄下面新建一個 pomelo 的文件夾,然後從 github 上把最新的 libpomelo 下載到 剛剛建的 pomelo 文件夾下面
enter image description here

4: 然後打開終端(windows 則打開 cygwin)
在項目目錄下敲入
ndk-build NDK_MODULE_PATH=/android項目絕對路徑/pomelo/
即可完成編譯

enter image description here

5: 如果是要結合cocos2d-x進行開發,那麼只需要把 libpomelo 放在 /cocos2dx絕對路徑/cocos2dx/platform/third_party/android/prebuilt 文件夾裏面,然後執行 ./build_native.sh 即可
具體可參考 cocos2d-x android

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章