-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Pomelo客户端开发
使用pomelo做服务端开发时,无论什么客户端,只要能遵循与服务端的线上协议,就能够与服务端建立通信。pomelo内建提供的sioconnector和hybridconnector都定义了自己的协议格式,其中sioconnector用于socket.io的通信,hybridconnector则用来处理websocket和tcp的连接通信。为了方便客户端的开发,pomelo提供了部分平台的客户端SDK,这里主要会介绍一下用于Web端的JavaScript的SDK以及基于C语言的libpomelo的使用。
对于浏览器来说,HTML5中已经支持了websocket,因此使用支持websocket的浏览器可以直接与服务端的hybridconnector建立通信。而对于比较旧的浏览器来说,还没有支持websocket的,可以使用基于socket.io的方式进行与服务端建立连接。因此,对于Web端,pomelo提供了两套开发库,分别适用于支持websocket的浏览器和不支持websocket的浏览器,这两套开发库的链接如下,适用于socket.io的pomelo-jsclient-socket.io以及适用于websocket的pomelo-jsclient-websocket。
对于使用socket.io的客户端SDK来说,其依赖socket.io-client, 由于这个库在使用component进行管理时有bug,因此在使用的时候,是直接引用其提供的js文件,具体引用的js文件为socket.io-client.js。对于pomelo-jsclient-socket.io来说,同样也是直接使用引用其js文件,也即是pomelo-client.js。在直接引用这两个文件后即可使用pomelo的调用了。
对于使用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 是 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;
}
// 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);
}
// 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);
}
- 创建一个新的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里面的脚本就行
./pomelo_gyp
xcodebuild -project pomelo.xcodeproj
./pomelo_gyp -DTO=ios
./build_ios
./pomelo_gyp -DTO=ios
./build_iossim
./pomelo_gyp
make
在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打开即可进行编译
开发前提条件:
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