新聞中心
前言

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專(zhuān)注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、微信平臺(tái)小程序開(kāi)發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶(hù)創(chuàng)新互聯(lián)還提供了化州免費(fèi)建站歡迎大家使用!
哈,這又是一個(gè)socket.io服務(wù)端實(shí)現(xiàn),本意是,拿C練練手,加強(qiáng)對(duì)C和linux系統(tǒng)的理解,寫(xiě)著寫(xiě)著,就寫(xiě)成了一個(gè)socket.io服務(wù)器端實(shí)現(xiàn)了。以為半成品,那就正式托管在github站點(diǎn)上吧,以便記錄一下,可讓大家批評(píng)與指正,加強(qiáng)內(nèi)功的修煉等。
項(xiàng)目地址為:yongboy/c_socket.io_server
以下部分文字,偷懶,摘錄自項(xiàng)目的README.md文件
說(shuō)明
這是一個(gè)純C語(yǔ)言版本的socket.io服務(wù)器端實(shí)現(xiàn),目前僅支持linux系統(tǒng),嚴(yán)重依賴(lài)libev and glib等基礎(chǔ)庫(kù)。
在運(yùn)行socket.io_server之前,需要安裝以下依賴(lài):
- sudo apt-get install uuid-dev
- sudo apt-get install libglib2.0-dev
如何運(yùn)行
- 編寫(xiě)實(shí)現(xiàn)代碼(eg:chatroom.c),需要包含頭文件 endpoint_impl.h
- 把實(shí)現(xiàn)代碼(eg:chatroom.c)放入examples目錄
- 編寫(xiě)對(duì)應(yīng)的html文件,放入static目錄
- 編輯Makefile文件
- 終端下運(yùn)行make命令
- 然后敲入 ./socket.io_server 接口運(yùn)行
- 打開(kāi)瀏覽器即可訪(fǎng)問(wèn) (eg:http://localhost:8000/chatroom.html)
API說(shuō)明
對(duì)外的API,可以在頭文件 endpoint_impl.h 看到其定義,其繼承了另外一個(gè)公用的頭文件 endpoint.h, 其完整定義為:
- #include
- #include
- #include
- typedef struct {
- char *message_type;
- char *message_id;
- char *endpoint;
- char *message_data;
- char *ori_data;
- } message_fields;
- typedef struct {
- char *endpoint;
- void (*on_init)(const char *endpoint);
- void (*on_connect)(const char *sessionid);
- void (*on_message)(const char *sessionid, const message_fields *msg_fields);
- void (*on_json_message)(const char *sessionid, const message_fields *msg_fields);
- void (*on_event)(const char *sessionid, const message_fields *msg_fields);
- void (*on_other)(const char *sessionid, const message_fields *msg_fields);
- void (*on_disconnect)(const char *sessionid, const message_fields *msg_fields);
- void (*on_destroy)(const char *endpoint);
- } endpoint_implement;
- extern void send_msg(char *sessionid, char *message);
- extern void broadcast_clients(char *except_sessionid, char *message);
- static void on_init(const char *endpoint);
- static void on_connect(const char *sessionid);
- static void on_message(const char *sessionid, const message_fields *msg_fields) {
- printf("on_message recevie ori msg is %s\n", msg_fields->ori_data);
- }
- static void on_json_message(const char *sessionid, const message_fields *msg_fields) {
- printf("on_json_message recevie ori msg is %s\n", msg_fields->ori_data);
- }
- static void on_other(const char *sessionid, const message_fields *msg_fields) {
- printf("on_other recevie ori msg is %s\n", msg_fields->ori_data);
- }
- static void on_event(const char *sessionid, const message_fields *msg_fields);
- static void on_disconnect(const char *sessionid, const message_fields *msg_fields);
- static void on_destroy(const char *endpoint);
- static endpoint_implement *init_default_endpoint_implement(char *endpoint_name) {
- endpoint_implement *impl_point = (endpoint_implement *)malloc(sizeof(endpoint_implement));
- impl_point->endpoint = strdup(endpoint_name);
- impl_point->on_init = on_init;
- impl_point->on_connect = on_connect;
- impl_point->on_message = on_message;
- impl_point->on_json_message = on_json_message;
- impl_point->on_event = on_event;
- impl_point->on_other = on_other;
- impl_point->on_disconnect = on_disconnect;
- impl_point->on_destroy = on_destroy;
- return impl_point;
- }
完整定義.
在example目錄中,你可以看到聊天室演示chatroom 和在線(xiàn)白板示范whiteboard .
- #include
- #include
- #include
- #include
- #include "../endpoint_impl.h"
- typedef struct {
- char *event_name;
- char *event_args;
- } event_message;
- static char *event_message_reg = "{\"name\":\"(.*?)\",\"args\":\\[([^\\]]*?)\\]}";
- static gchar *get_match_result(GMatchInfo *match_info, gint index) {
- gchar *match = g_match_info_fetch(match_info, index);
- gchar *result = g_strdup(match);
- g_free(match);
- return result;
- }
- static void *message_2_struct(gchar *post_string, event_message *event_msg) {
- GError *error = NULL;
- GRegex *regex;
- GMatchInfo *match_info;
- regex = g_regex_new(event_message_reg, 0, 0, &error );
- g_regex_match( regex, post_string, 0, &match_info );
- if (g_match_info_matches(match_info)) {
- event_msg->event_name = get_match_result(match_info, 1);
- event_msg->event_args = get_match_result(match_info, 2);
- } else {
- event_msg = NULL;
- }
- g_match_info_free( match_info );
- g_regex_unref( regex );
- return event_msg;
- }
- static GHashTable *hashtable;
- static void hashtable_init(void) {
- hashtable = g_hash_table_new(g_str_hash, g_str_equal);
- }
- static void hashtable_add(const char *key, void *value) {
- if (key) {
- g_hash_table_insert(hashtable, g_strdup(key), value);
- }
- }
- static gboolean hashtable_remove(const char *key) {
- if (key)
- return g_hash_table_remove(hashtable, key);
- return 0;
- }
- static void *hashtable_lookup(const char *key) {
- if (key == NULL)
- return NULL;
- return g_hash_table_lookup(hashtable, key);
- }
- /*static gint hashtable_size(void) {
- return g_hash_table_size(hashtable);
- }*/
- static void hashtable_destroy(void) {
- g_hash_table_destroy(hashtable);
- }
- /**
- ** use the struct to warpper the demo implment
- **/
- static char *endpoint_name;
- static void on_init(const char *endpoint) {
- hashtable_init();
- printf("%s has been inited now\n", endpoint);
- endpoint_name = g_strdup(endpoint);
- }
- static void on_connect(const char *sessionid) {
- char messages[strlen(sessionid) + 50];
- sprintf(messages, "5::%s:{\"name\":\"clientId\",\"args\":[{\"id\":\"%s\"}]}", endpoint_name, sessionid);
- send_msg(sessionid, messages);
- }
- static void send_it(char *session_id, char *messaage) {
- send_msg(session_id, messaage);
- }
- static void free_event_msg(event_message *event_msg) {
- free(event_msg->event_name);
- free(event_msg->event_args);
- }
- static void on_event(const char *sessionid, const message_fields *msg_fields) {
- event_message event_msg;
- if (!message_2_struct(msg_fields->message_data, &event_msg)) {
- fprintf(stderr, "%s Parse Message Error !\n", msg_fields->ori_data);
- return;
- }
- if (!strcmp(event_msg.event_name, "roomNotice")) {
- /*5::/whiteboard:{"name":"roomNotice","args":[{"room":"myRoom"}]}*/
- char target_room_id[strlen(event_msg.event_args) - 10];// = event_msg.event_args + 9;
- strncpy(target_room_id, event_msg.event_args + 9, strlen(event_msg.event_args) - 11);
- GPtrArray *list = (GPtrArray *)hashtable_lookup(target_room_id);
- if (list == NULL) {
- list = g_ptr_array_new();
- hashtable_add(target_room_id, list);
- }
- g_ptr_array_add(list, g_strdup(sessionid));
- int room_count = list->len;
- char messages[strlen(sessionid) + 200];
- sprintf(messages, "5::%s:{\"name\":\"roomCount\",\"args\":[{\"room\":\"%s\",\"num\":%d}]}", endpoint_name, target_room_id, room_count);
- hashtable_add(g_strdup(sessionid), g_strdup(target_room_id));
- g_ptr_array_foreach(list, (GFunc)send_it, messages);
- free_event_msg(&event_msg);
- return;
- }
- char messages[strlen(msg_fields->ori_data) + 200];
- sprintf(messages, "5::%s:{\"name\":\"%s\",\"args\":[%s]}", endpoint_name, event_msg.event_name, event_msg.event_args);
- free_event_msg(&event_msg);
- char *target_room_id = (char *)hashtable_lookup(sessionid);
- GPtrArray *list = (GPtrArray *)hashtable_lookup(target_room_id);
- if(list == NULL){
- return;
- }
- int i;
- for (i = 0; i < list->len; i++) {
- char *session_id = g_ptr_array_index(list, i);
- if (strcmp(session_id, sessionid) == 0)
- continue;
- send_msg(session_id, messages);
- }
- }
- static void on_disconnect(const char *sessionid, const message_fields *msg_fields) {
- char *room_id = (char *)hashtable_lookup(sessionid);
- if (room_id == NULL) {
- fprintf(stderr, "the room_id is NULL\n");
- return;
- }
- char notice_msg[strlen(endpoint_name) + strlen(room_id) + 70];
- GPtrArray *list = (GPtrArray *)hashtable_lookup(room_id);
- sprintf(notice_msg, "5::%s:{\"name\":\"roomCount\",\"args\":[{\"room\":\"%s\",\"num\":%d}]}", endpoint_name, room_id, list->len - 1);
- int i, remove_index;
- for (i = 0; i < list->len; i++) {
- char *session_id = g_ptr_array_index(list, i);
- if (strcmp(session_id, sessionid) == 0) {
- remove_index = i;
- continue;
- }
- send_msg(session_id, notice_msg);
- }
- g_ptr_array_remove_index(list, remove_index);
- hashtable_remove(sessionid);
- free(room_id);
- }
- static void on_destroy(const char *endpoint) {
- printf("%s has been destroy now\n", endpoint);
- hashtable_destroy();
- free(endpoint_name);
- }
- extern endpoint_implement *init_whiteboard_endpoint_implement(char *endpoint_name) {
- return init_default_endpoint_implement(endpoint_name);
- }
因?yàn)镃語(yǔ)言中沒(méi)有散列表,只好借助于成熟的glib庫(kù)實(shí)現(xiàn)。
其它
項(xiàng)目不太成熟,期待大家的參與,您的建議、批評(píng)和指正,都是一種激勵(lì),再次表示感謝。
當(dāng)前名稱(chēng):純C語(yǔ)言版本的socket.io服務(wù)器端實(shí)現(xiàn)
地址分享:http://m.5511xx.com/article/dhdjiji.html


咨詢(xún)
建站咨詢(xún)
