使用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版本以後的協議
依賴
使用
創建客戶端實例
// 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 的 工程,建完之後如圖:
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 文件夾下面
4: 然後打開終端(windows 則打開 cygwin)
在項目目錄下敲入
ndk-build NDK_MODULE_PATH=/android項目絕對路徑/pomelo/
即可完成編譯
5: 如果是要結合cocos2d-x進行開發,那麼只需要把 libpomelo 放在 /cocos2dx絕對路徑/cocos2dx/platform/third_party/android/prebuilt 文件夾裏面,然後執行 ./build_native.sh 即可
具體可參考 cocos2d-x android