av2020不卡,日韩欧美精品在线视频,亚洲成人国产精品http://www.aygfsteel.com/yongboy/category/54838.html記錄工作/學(xué)習(xí)的點(diǎn)點(diǎn)滴滴。zh-cnMon, 01 Jun 2015 04:03:10 GMTMon, 01 Jun 2015 04:03:10 GMT60c_socket.io_server筆記之定義私有接口http://www.aygfsteel.com/yongboy/archive/2013/03/29/397154.htmlnieyongnieyongFri, 29 Mar 2013 09:18:00 GMThttp://www.aygfsteel.com/yongboy/archive/2013/03/29/397154.htmlhttp://www.aygfsteel.com/yongboy/comments/397154.htmlhttp://www.aygfsteel.com/yongboy/archive/2013/03/29/397154.html#Feedback0http://www.aygfsteel.com/yongboy/comments/commentRss/397154.htmlhttp://www.aygfsteel.com/yongboy/services/trackbacks/397154.html有些話說

頭文件可以作為接口定義,再加上static修飾符,就很容易定義私有的接口,每一個(gè)具體的實(shí)現(xiàn),即所有包含所有私有接口的頭文件,都必須要完整實(shí)現(xiàn)所有已聲明但未實(shí)現(xiàn)的函數(shù),否則gcc編譯不過去。廢話不多說,進(jìn)入步驟吧。

開始實(shí)施

以毫無用處的blog為例,簡單兩個(gè)方法就行了,需要每一個(gè)實(shí)現(xiàn)暴露一個(gè)可以外部調(diào)用函數(shù)。

定義一個(gè)結(jié)構(gòu),公用

blog.h:

    #ifndef _BLOG_H
    
#define _BLOG_H
    
    typedef 
struct {
        
char *name;
        
void (*init)(void);
        
void (*welcome)(void);
    } blog_t;
    
    
#endif

這個(gè)頭文件定義了一個(gè)對(duì)象??梢宰杂傻谋话?,包含之后自由使用blog_t結(jié)構(gòu)。

定義一個(gè)完全私有函數(shù)頭文件

blog_impl.h:

#ifndef _BLOG_IMPL_H
#define _BLOG_IMPL_H

#include 
<stdlib.h>
#include 
<stdio.h>
#include 
<string.h>

#include 
"blog.h" //繼承blog.h文件

static void welcome(void);
static void init(void);

static blog_t *gen_default(char *name) {
    blog_t 
*blog = (blog_t *)malloc(sizeof(blog_t));
    blog
->name = strdup(name);
    blog
->init = init;
    blog
->welcome = welcome;

    
return blog;
}

#endif

這個(gè)文件聲明定義了若干static屬性的函數(shù),因此,只要包含此頭文件的C源文件,必須實(shí)現(xiàn)welcomeinit函數(shù),否則gcc編譯不通過。需要注意此頭文件私有。

編寫實(shí)現(xiàn)

blog1.c,僅僅一個(gè)實(shí)現(xiàn):

#include "blog_impl.h"

static blog_t *this;

static void init(void){
    printf(
"the blog owner is %s\n"this->name);
}

static void welcome(void){
    printf(
"here is the %s haha !\n"this->name);
}

blog_t 
*gen_blog1_ptr(){
    blog_t 
*blog = gen_default("blog1");
    
this = blog;

    
return blog;
}

僅有一個(gè)對(duì)外入口:gen_blog1_ptr,也就是此實(shí)現(xiàn)對(duì)外唯一的交互方式。

blog2.c,默認(rèn)的實(shí)現(xiàn):

#include "blog_impl.h"

static void init(void){
    printf(
"Here is the default blog init action !\n");
}

static void welcome(void){
    printf(
"The system's welcome action !\n");
}

blog_t 
*gen_blog2_ptr(){
    blog_t 
*blog = gen_default("default");

    
return blog;
}

此文件對(duì)外唯一入口為:gen_blog2_ptr。

其實(shí)兩個(gè)實(shí)現(xiàn)已經(jīng)可以了,但多一個(gè)說明接口單一,實(shí)現(xiàn)多樣性,再說錦上添花也是人們喜歡做的事情。 blog3.c,添花版:

#include "blog_impl.h"

static blog_t *this;

static void init(void){
    printf(
"Hi, %s\n"this->name);
}

static void welcome(void){
    printf(
"you are welcome %s!\n"this->name);
}

blog_t 
*gen_blog3_ptr(){
    blog_t 
*blog = gen_default("blog3");
    
this = blog;

    
return blog;
}

一樣可以看到類似約定好的對(duì)外函數(shù)名稱gen_blog3_ptr

應(yīng)用端實(shí)現(xiàn)

我們以app.c作為應(yīng)用入口:

#include <stdio.h>
#include 
<stdlib.h>

#include 
"blog.h"

int main(int argc, char const *argv[]) {
    blog_t 
*blog1 = gen_blog1_ptr();
    blog_t 
*blog2 = gen_blog2_ptr();
    blog_t 
*blog3 = gen_blog3_ptr();

    printf(
"the blog1's actions \n");
    blog1
->init();
    blog1
->welcome();
    printf(
"\n");

    printf(
"the blog2's actions \n");
    blog2
->init();
    blog2
->welcome();
    printf(
"\n");

    printf(
"the blog3's actions \n");
    blog3
->init();
    blog3
->welcome();
    printf(
"\n");

    
return 0;
}

這里分別調(diào)用blog1.c, blog2.c, blog3.c,唯一入口,執(zhí)行簡單的邏輯。

編譯運(yùn)行

編譯命令行代碼很簡單:

gcc -o app app.c blog1.c blog2.c blog3.c

運(yùn)行:

./app

運(yùn)行效果:

the blog1's actions ...
the blog owner is blog1
here is the blog1 haha !

the blog2's actions ... Here is the default blog init action !
The system's welcome action !

the blog3's actions ...
Hi, blog3
you are welcome blog3!

小結(jié)

這里借助兩個(gè)頭文件,模擬了私有接口,公有結(jié)構(gòu)體對(duì)象,三個(gè)具體子類實(shí)現(xiàn)。
c_socket.io_server項(xiàng)目中,作用于具體的實(shí)現(xiàn),以及定義了傳輸通道模型和實(shí)現(xiàn),互相不干擾。
當(dāng)然和JAVA相比,模擬對(duì)象程度稍低了一些,但夠用了。這個(gè)世界不僅僅只有面向?qū)ο螅€有面向并發(fā)的函數(shù)式Erlang,還有面向軟件工程的大型語言Go。嗯,面向?qū)ο蟛贿^是這個(gè)世界其中一角,天生存在缺陷,也不是被所有人喜歡。組件公用、庫的概念,倒是大部分語言都很自然的欣然接受。面向過程,面向?qū)ο?,不過是大部分人給與的標(biāo)簽,怎么用才重要。



nieyong 2013-03-29 17:18 發(fā)表評(píng)論
]]>
c_socket.io_server筆記之htmlfile塊傳輸http://www.aygfsteel.com/yongboy/archive/2013/03/28/397081.htmlnieyongnieyongThu, 28 Mar 2013 00:41:00 GMThttp://www.aygfsteel.com/yongboy/archive/2013/03/28/397081.htmlhttp://www.aygfsteel.com/yongboy/comments/397081.htmlhttp://www.aygfsteel.com/yongboy/archive/2013/03/28/397081.html#Feedback0http://www.aygfsteel.com/yongboy/comments/commentRss/397081.htmlhttp://www.aygfsteel.com/yongboy/services/trackbacks/397081.html關(guān)于htmlfile chunked傳輸

Google天才工程師們使用一個(gè)稱為“htmlfile”的 ActiveX 解決了在 IE 中的加載顯示問題,具體是封裝了一個(gè)基于 iframe 和 htmlfile 的 JavaScript comet 對(duì)象,支持 IE、Mozilla Firefox 瀏覽器,但需要服務(wù)器端配合使用。
稍微熟悉一下有關(guān)Transfer-Encoding: chunked的同學(xué),會(huì)感覺一點(diǎn)技術(shù)含量都沒有。但那是他們的事情,笨鳥先飛,記錄下來,以作備忘。
我們做一個(gè)時(shí)間顯示,每隔一秒自動(dòng)顯示在頁面上。那么做這件事情的順序,就很簡單。

輸出頭部

chunked塊傳輸,需要瀏覽器支持,服務(wù)器需要提前告訴瀏覽器端:

#define HTMLFILE_RESPONSE_HEADER \
"HTTP/1.1 200 OK\r\n" \
"Connection: keep-alive\r\n" \
"Content-Type: text/html; charset=utf-8\r\n" \
"Transfer-Encoding: chunked\r\n" \
"\r\n"......
write_ori(client, HTMLFILE_RESPONSE_HEADER);

在socket.io服務(wù)器中,數(shù)據(jù)量不大,傳輸內(nèi)容無須gzip壓縮,畢竟壓縮算法要耗費(fèi)一些CPU時(shí)間。

傳輸部分HTML預(yù)備內(nèi)容

這部分不是必須的,為了調(diào)用客戶端javascript方便,可以提前定義好調(diào)用函數(shù)。

#define HTMLFILE_RESPONSE_FIRST \
    "<html><head><title>htmlfile chunked example</title><script>var _ = function (msg) { document.getElementById('div').innerHTML = msg; };</script></head><body><div id=\"div\"></div>"......
char target_message[strlen(HTMLFILE_RESPONSE_FIRST) + 20];
sprintf(target_message, "%X\r\n%s\r\n", (int)strlen(HTMLFILE_RESPONSE_FIRST), HTMLFILE_RESPONSE_FIRST);
write_ori(client, target_message);

除了http header頭部輸出,剩下內(nèi)容的輸出,需要注意輸出的簡單格式:

具體輸出內(nèi)容長度16進(jìn)制數(shù)字表示\r\n具體輸出內(nèi)容\r\n

2D
<script>_('now time is 1364040943');</script>

掌握了格式要求之后,其它的,就沒有什么難點(diǎn)。

設(shè)置定時(shí)器,周期性循環(huán)

client->timeout.data = client;
ev_timer_init(&client->timeout, timeout_cb, 1.0, 1.0);
ev_timer_start(loop, &client->timeout);

時(shí)間觸發(fā)函數(shù)timeout_cb每一秒會(huì)定時(shí)觸發(fā):

static void timeout_cb(EV_P_ struct ev_timer *timer, int revents) {
if (EV_ERROR & revents) {
    fprintf(stderr, "error event in timer_beat\n");
    return ;
}
if (timer == NULL) {
    fprintf(stderr, "the timer is NULL now !\n");
}
client_t *client = timer->data;
if (client == NULL) {
     fprintf(stderr, "Timeout the client is NULL !\n");
    return;
}
char target_msg[50];
snprintf(target_msg, 50, "now time is %d", (int)ev_time());
write_body(client, target_msg);
}

OK,基本功能完畢。

編譯運(yùn)行

編譯一下:

gcc htmlfile.c -o htmlfile ../include/libev.a -lm

運(yùn)行它:

./htmlfile

打開瀏覽器,輸入地址 http://192.168.190.150:8080/htmlfile,可以看到時(shí)間一點(diǎn)點(diǎn)的流逝,諸如:

now time is 1364043695

完整代碼



nieyong 2013-03-28 08:41 發(fā)表評(píng)論
]]>
c_socket.io_server筆記之長輪詢超時(shí)(timeout)處理http://www.aygfsteel.com/yongboy/archive/2013/03/27/397031.htmlnieyongnieyongWed, 27 Mar 2013 00:57:00 GMThttp://www.aygfsteel.com/yongboy/archive/2013/03/27/397031.htmlhttp://www.aygfsteel.com/yongboy/comments/397031.htmlhttp://www.aygfsteel.com/yongboy/archive/2013/03/27/397031.html#Feedback0http://www.aygfsteel.com/yongboy/comments/commentRss/397031.htmlhttp://www.aygfsteel.com/yongboy/services/trackbacks/397031.html不吐不快

當(dāng)你習(xí)慣了現(xiàn)有WEB服務(wù)器,諸如nginx、apache,JAVA應(yīng)用服務(wù)器Tomcat等,你就不能不注意HTTP請(qǐng)求的響應(yīng)超時(shí)時(shí)間,需要小心,尤其是反向代理時(shí)。當(dāng)你可以自由控制請(qǐng)求timeout超時(shí)時(shí),那是怎樣一個(gè)快意。
在libev中使用timeout,沒有像java那樣封裝的完善,一切都很原始,但確實(shí)鋒利多了。

長輪詢

一般長輪詢需要定義超時(shí)時(shí)間,一旦超時(shí),服務(wù)器端會(huì)主動(dòng)斷開連接。無論是xhr形式的長輪詢,還是jsonp長輪詢,在服務(wù)器端處理沒有多大差別,輸出數(shù)據(jù)有異。

輸出頭部

一般優(yōu)先輸出頭部,告訴瀏覽器,需要保持長連接,當(dāng)然,這需要瀏覽器支持http 1.1協(xié)議,并且明確的注明當(dāng)前連接為一直保持著:keep-alive:

char heaer_str[200= "";
strcat(heaer_str, 
"HTTP/1.1 200 OK\r\n");
strcat(heaer_str, 
"Content-Type: text/plain; charset=UTF-8\r\n");
strcat(heaer_str, 
"Connection: keep-alive\r\n");
strcat(heaer_str, 
"\r\n");
write_msg(client, heaer_str);

定時(shí)器啟動(dòng),等待

連接什么時(shí)候關(guān)閉,需要在代碼中手動(dòng)控制,除非瀏覽器端在發(fā)出請(qǐng)求等待響應(yīng)期間出現(xiàn)異常,無故斷開了連接。設(shè)服務(wù)器端設(shè)定好連接持續(xù)時(shí)間為30秒,那么就應(yīng)該啟動(dòng)一個(gè)定時(shí)器,除非所使用的語言層面提供了內(nèi)置支持。

client->timeout.data = client;
ev_timer_init(
&client->timeout, timeout_cb, 30.00); //30s
ev_timer_start(loop, &client->timeout);

定時(shí)器start之后,觸發(fā)的函數(shù)timeout_cb:

 1     static void timeout_cb(EV_P_ struct ev_timer *timer, int revents) {
 2         if (EV_ERROR & revents) {
 3             fprintf(stderr, "error event in timer_beat\n");
 4             return ;
 5         }
 6     
 7         if (timer == NULL) {
 8             fprintf(stderr, "the timer is NULL now !\n");
 9             return;
10         }
11     
12         client_t *client = timer->data;
13     
14         if (client == NULL) {
15             fprintf(stderr, "Timeout the client is NULL !\n");
16             return;
17         }
18     
19         write_msg(client, HTML_RESPONSE_ECHO);
20         free_res(loop, client);
21     }

可以看到,定時(shí)器觸發(fā)之后,本例中將輸出一串預(yù)先定義好的文字,然后關(guān)閉連接。
如何關(guān)閉觸發(fā)器,則很簡單:


    ev_timer *timer = &client->timeout;
    
if (timer != NULL && (timer->data != NULL)) {
        ev_timer_stop(loop, timer);
    }

編譯運(yùn)行

編譯一下:

gcc longpolling.c -o longpolling ../include/libev.a ../include/http-parser/http_parser.o -lm

運(yùn)行它:

./long_polling

然后測試:

curl -i http://192.168.190.150:9000/long_polling

可以先看到頭部:

HTTP/1.1 200 OK Content-Type: text/plain; charset=UTF-8 Connection: keep-alive

等到30秒后輸出具體的文字內(nèi)容:

The timeout(30s) had passed, you are welcome ~!

小結(jié)

所演示的長輪詢,沒有什么難度,HTTP 1.1頭部輸出,定時(shí)器啟動(dòng),然后等待輸出。
libev內(nèi)含的timer組件簡單易用,控制方便,但不算是最佳實(shí)踐,官方文檔給出了若干種最佳實(shí)踐方式。具體可參閱:
http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#codeevtimercoderelativeandopti

完整代碼



nieyong 2013-03-27 08:57 發(fā)表評(píng)論
]]>
c_socket.io_server筆記之處理靜態(tài)文件http://www.aygfsteel.com/yongboy/archive/2013/03/25/396972.htmlnieyongnieyongMon, 25 Mar 2013 08:46:00 GMThttp://www.aygfsteel.com/yongboy/archive/2013/03/25/396972.htmlhttp://www.aygfsteel.com/yongboy/comments/396972.htmlhttp://www.aygfsteel.com/yongboy/archive/2013/03/25/396972.html#Feedback0http://www.aygfsteel.com/yongboy/comments/commentRss/396972.htmlhttp://www.aygfsteel.com/yongboy/services/trackbacks/396972.html緣由

在編 寫純C語言版socket.io服務(wù)器 時(shí),選擇了libev作為網(wǎng)絡(luò)基礎(chǔ)層代碼,可以離epoll模型遠(yuǎn)一些,再說還可以避免單獨(dú)使用Epoll,寫出不易維護(hù)的多層嵌套代碼,聽說,有時(shí)Epoll出現(xiàn)一些“偽信號(hào)”小問題,沒有那么空閑精力,繞過之,選擇成熟度非常高的libev好了。
有關(guān)libev的文章,中文資料不多,英文資料也不多。這里推薦三篇:
- libev 設(shè)計(jì)分析
- libev ev_io源碼分析
- 官方文檔http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod,更為全面一些,閱讀時(shí)可以獲得較總體認(rèn)知。

這里把在編寫c_socket.io_server程中使用libev的一些地方做些筆記,記錄下來,也方便以后查閱。

預(yù)備知識(shí)

所有代碼的編寫、編譯、測試和運(yùn)行等,都在Ubuntu下進(jìn)行,另外實(shí)例嚴(yán)重依賴libev和http-parser HTTP解析庫。
其它依賴,可以從https://github.com/yongboy/csocket.ioserver處下載。

處理靜態(tài)文件

這里設(shè)計(jì)一個(gè)靜態(tài)文件WEB服務(wù)器,非常簡單,僅僅滿足socket.io服務(wù)器最基本的需求,因此別苛求太多。但比網(wǎng)上很多大把類似文章多了一點(diǎn)寫入管道時(shí)緩沖區(qū)已滿問題的處理。
這里簡單說一下處理靜態(tài)文件的思路。

計(jì)算靜態(tài)文件路徑以及擴(kuò)展名和內(nèi)容類型

char file_path[200]; 
sprintf(file_path, "%s%s", static_folder, url_str);

獲取文件內(nèi)容和以及優(yōu)先輸出響應(yīng)頭部

    char file_path[200];
    sprintf(file_path, "%s%s", static_folder, url_str);

    int file = open(file_path, O_RDONLY);
    struct stat info;
    if (fstat(file, &info) == -1) {
        fprintf(stderr, "the file %s is NULL\n", file_path);
        write(client->fd, RESPONSE_404, strlen(RESPONSE_404));

        close(file);
        free_res(loop, client);

        return 0;
    }

    char file_ext[50];
    get_extension(file_path, file_ext);
    char content_type[50];
    get_content_type(file_ext, content_type);

    int file_len = info.st_size;
    char head_msg[200] = "";
    sprintf(head_msg, RESPONSE_TEMPLATE, content_type, file_len);
    write(client->fd, head_msg, strlen(head_msg));

很顯然,這里引入fcntl.h頭部文件,調(diào)用fstat初始化stat結(jié)構(gòu),可判斷文件是否存在,以及文件大小等。

讀取文件內(nèi)容到緩沖區(qū),循環(huán)寫入

int read_count;
int buf_size = 8 * 1024;//8096;
char buffer[buf_size + 1];
while ((read_count = read(file, buffer, buf_size)) > 0) {
int bytes_left = read_count;
char *ptr = buffer;
int need_break = 0;
while (bytes_left > 0) {
ssize_t write_len = write(client->fd, ptr, bytes_left);

if (write_len == -1) {
fprintf(stderr, "write failed(errno = %d): %s\n", errno, strerror(errno));
switch (errno) {
case EAGAIN:
case EINTR:
case EINPROGRESS:
fprintf(stderr, "now sleep 0.2s\n");
ev_sleep(0.2);
break;
default:
need_break = 1;
break;
}
} else if (write_len == 0) {
need_break = 1;
fprintf(stderr, "write_len is zero, and break now\n");
break;
} else if (write_len < bytes_left) {
bytes_left -= write_len;
ptr += write_len;
fprintf(stderr, "write client with something wrong wtih bytes_left = %d & write_len = %d and write the left data !\n", (int)bytes_left, (int)write_len);
} else {
break;
}
}

if (need_break) {
break;
}
}

close(file);

需要注意,構(gòu)造的一個(gè)大約8K+1的緩沖區(qū)buffer,不是每次都可以正常完整輸出到socket對(duì)端,write輸出不完整,會(huì)返回-1,系統(tǒng)返回errno值,在errno = EAGAIN,EINTR,EINPROGRESS時(shí),需要再次將緩沖區(qū)中尚未寫入的剩下數(shù)據(jù)再次寫入到請(qǐng)求端。這樣可以避免常見的半包、包不完整問題。

關(guān)閉socket描述符,當(dāng)前請(qǐng)求結(jié)束

free_res(loop, client);

請(qǐng)求完成,一定要記得關(guān)閉socket描述符,釋放相應(yīng)資源等。 這樣一個(gè)較為完整的HTTP請(qǐng)求,靜態(tài)文件就處理完畢了。

編譯運(yùn)行

先編譯:

gcc staticserver.c -o staticserver ../include/libev.a ../include/http-parser/http_parser.o -lm

運(yùn)行之:

./static_server ../static

命令輸入錯(cuò)誤,如輸入靜態(tài)路徑為空,會(huì)報(bào)錯(cuò)的,哈哈:

Error: invald path parmeter

Usage: ./static_server

Example:
./staticserver ../static
./static
server /home/yongboy/yourstaticfolder

Enjoy it~

測試一下吧

curl -i http://192.168.190.150:8000/index.html

在瀏覽器內(nèi),測試一下,支持圖片樣式等,完好顯示。

需要注意,要傳入靜態(tài)文件目錄路徑,相對(duì)的路徑,或絕對(duì)的路徑,都是可以接受的。 最后,附上完整代碼:



nieyong 2013-03-25 16:46 發(fā)表評(píng)論
]]>
哈,又來一個(gè)純C語言版本的socket.io服務(wù)器端實(shí)現(xiàn)~http://www.aygfsteel.com/yongboy/archive/2013/03/15/396493.htmlnieyongnieyongFri, 15 Mar 2013 08:02:00 GMThttp://www.aygfsteel.com/yongboy/archive/2013/03/15/396493.htmlhttp://www.aygfsteel.com/yongboy/comments/396493.htmlhttp://www.aygfsteel.com/yongboy/archive/2013/03/15/396493.html#Feedback1http://www.aygfsteel.com/yongboy/comments/commentRss/396493.htmlhttp://www.aygfsteel.com/yongboy/services/trackbacks/396493.html前言

哈,這又是一個(gè)socket.io服務(wù)端實(shí)現(xiàn),本意是,拿C練練手,加強(qiáng)對(duì)C和linux系統(tǒng)的理解,寫著寫著,就寫成了一個(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文件

說明

這是一個(gè)純C語言版本的socket.io服務(wù)器端實(shí)現(xiàn),目前僅支持linux系統(tǒng),嚴(yán)重依賴libev and glib等基礎(chǔ)庫。
在運(yùn)行socket.io_server之前,需要安裝以下依賴:

sudo apt-get install uuid-dev
sudo apt-get install libglib2.0-dev

如何運(yùn)行

  1. 編寫實(shí)現(xiàn)代碼(eg:chatroom.c),需要包含頭文件 endpoint_impl.h
  2. 把實(shí)現(xiàn)代碼(eg:chatroom.c)放入examples目錄
  3. 編寫對(duì)應(yīng)的html文件,放入static目錄
  4. 編輯Makefile文件
  5. 終端下運(yùn)行make命令
  6. 然后敲入 ./socket.io_server 接口運(yùn)行
  7. 打開瀏覽器即可訪問 (eg:http://localhost:8000/chatroom.html)

API說明

對(duì)外的API,可以在頭文件 endpoint_impl.h 看到其定義,其繼承了另外一個(gè)公用的頭文件 endpoint.h, 其完整定義為:

完整定義.
在example目錄中,你可以看到聊天室演示 chatroom 和在線白板示范 whiteboard . 因?yàn)镃語言中沒有散列表,只好借助于成熟的glib庫實(shí)現(xiàn)。

其它

項(xiàng)目不太成熟,期待大家的參與,您的建議、批評(píng)和指正,都是一種激勵(lì),再次表示感謝。



nieyong 2013-03-15 16:02 發(fā)表評(píng)論
]]>
剛出爐的,socket.io erlang server版本,有點(diǎn)小清新http://www.aygfsteel.com/yongboy/archive/2012/10/15/389575.htmlnieyongnieyongMon, 15 Oct 2012 06:57:00 GMThttp://www.aygfsteel.com/yongboy/archive/2012/10/15/389575.htmlhttp://www.aygfsteel.com/yongboy/comments/389575.htmlhttp://www.aygfsteel.com/yongboy/archive/2012/10/15/389575.html#Feedback1http://www.aygfsteel.com/yongboy/comments/commentRss/389575.htmlhttp://www.aygfsteel.com/yongboy/services/trackbacks/389575.html絮言

最近在學(xué)習(xí)Erlang,順便寫了一個(gè)socket.io server作為練練手,感受函數(shù)式/面向并發(fā)編程的好處。

毫無疑問,同樣兼容最新的socket.io spec 1.0。

無論哪一種語言,從頭開始構(gòu)建HTTP協(xié)議支持,都是很痛苦的,站在巨人肩上,總是可以讓你更專注于業(yè)務(wù)。Java社區(qū)可選擇netty,Erlang社區(qū)可以選擇非常輕量級(jí)的mochiwebcowboy等,這里要感謝一下尤日華同學(xué)(http://www.cnblogs.com/yourihua/),特別熱心,一一給我們分析了以上兩個(gè)http框架的源碼,我等新手獲益良多。就是在其文章的幫助下,開始構(gòu)建一個(gè)socket.io erlang server。

mochiweb,有些歷史,已趨于穩(wěn)定,但目前不支持websocket協(xié)議。

cowboy,模塊/協(xié)議自由替換,使用二進(jìn)制傳輸基本保證了低內(nèi)存占用和快速傳輸,內(nèi)置非常贊的dispatch URL分發(fā)器,內(nèi)置對(duì)長連接的支持,目前使用的是0.6.1版本。推薦使用!

閑話少說,目前已經(jīng)釋出0.1版本,項(xiàng)目地址為:

https://code.google.com/p/erlang-scoketio/

項(xiàng)目介紹

Erlang 版本的socket.io服務(wù)器實(shí)現(xiàn)

1. 基于cowboy構(gòu)建

檢出地址: https://erlang-scoketio.googlecode.com/svn/socket.io_cowboy
兼容 socket.io-spec(https://github.com/LearnBoost/socket.io-spec) 1.0
支持xhr-polling/jsonp-polling/htmlfile/websocket/flashsocket等通訊協(xié)議
支持CJK語言,UTF-8編碼下很少出現(xiàn)亂碼
現(xiàn)在可以作為0.1版本釋出,具有一個(gè)chat示范

2. 基于mochiweb構(gòu)建

檢出地址: https://erlang-scoketio.googlecode.com/svn/socket.io_mochiweb
兼容 socket.io-spec(https://github.com/LearnBoost/socket.io-spec) 1.0
僅支持xhr-polling/jsonp-polling/htmlfile等通訊協(xié)議
暫時(shí)精力有限,停止更新,假若有需要,可以進(jìn)一步有償商談

3. 運(yùn)行一個(gè)示范

一個(gè)實(shí)現(xiàn)

這里介紹一個(gè)聊天示范,看代碼,很簡單,也很短,才80行。

與Java相比,Erlang代碼顯得少多了。

其它

剛?cè)腴T,項(xiàng)目代碼寫的有些草;您若慷慨,希望給些指點(diǎn),謝謝 :))



nieyong 2012-10-15 14:57 發(fā)表評(píng)論
]]>
Javascript EventBus(事件總線)模擬socket.io中事件處理http://www.aygfsteel.com/yongboy/archive/2012/08/24/386239.htmlnieyongnieyongFri, 24 Aug 2012 15:04:00 GMThttp://www.aygfsteel.com/yongboy/archive/2012/08/24/386239.htmlhttp://www.aygfsteel.com/yongboy/comments/386239.htmlhttp://www.aygfsteel.com/yongboy/archive/2012/08/24/386239.html#Feedback0http://www.aygfsteel.com/yongboy/comments/commentRss/386239.htmlhttp://www.aygfsteel.com/yongboy/services/trackbacks/386239.htmlsocket.io客戶端對(duì)事件處理相當(dāng)優(yōu)雅,和weboscket的有限的javascript接口差不多一致好看,但可以支持更多的自定義事件:

使用了EventBus(事件總線)方式可以很好的處理事件訂閱者/事件的發(fā)布者解耦,發(fā)布者不知道訂閱者,訂閱者只需要自身注冊(cè),等待通知便可。EventBus是一種簡單,高效,優(yōu)雅,良好的客戶端架構(gòu)方式。嗯,還好,javascritp本身支持函數(shù)作為參數(shù)進(jìn)行傳遞,要不還是很麻煩的。

構(gòu)建一個(gè)最簡單的EventBus javascript庫,也不難:

簡單不到40行代碼,提供了事件訂閱,事件取消,事件廣播/發(fā)布等,雖簡單,但已經(jīng)滿足最簡單的頁面端EventBus模型,可以一窺全貌了。

客戶端使用事件總線代碼:

看著和socket.io的客戶端使用方式有所類似,但socket.io的處理方式復(fù)雜多了,并且多了一些內(nèi)置的事件,這里不過是簡化了很多。

嗯,有空談一談JAVA是如何做到事件總線(EventBus)的。



nieyong 2012-08-24 23:04 發(fā)表評(píng)論
]]>
Real-Time Web實(shí)時(shí)信息流推送培訓(xùn)文檔http://www.aygfsteel.com/yongboy/archive/2012/08/23/386061.htmlnieyongnieyongThu, 23 Aug 2012 01:57:00 GMThttp://www.aygfsteel.com/yongboy/archive/2012/08/23/386061.htmlhttp://www.aygfsteel.com/yongboy/comments/386061.htmlhttp://www.aygfsteel.com/yongboy/archive/2012/08/23/386061.html#Feedback6http://www.aygfsteel.com/yongboy/comments/commentRss/386061.htmlhttp://www.aygfsteel.com/yongboy/services/trackbacks/386061.html培訓(xùn)演示文檔,文檔大綱:
推送實(shí)現(xiàn)技術(shù)/歷程
客戶端如何選擇
Java支持現(xiàn)狀
socket.io
Realtime Web概念和現(xiàn)狀
  閱讀全文

nieyong 2012-08-23 09:57 發(fā)表評(píng)論
]]>
構(gòu)建實(shí)時(shí)Web的JAVA選擇組合:socket.io client + socketio-netty serverhttp://www.aygfsteel.com/yongboy/archive/2012/05/24/378839.htmlnieyongnieyongThu, 24 May 2012 01:10:00 GMThttp://www.aygfsteel.com/yongboy/archive/2012/05/24/378839.htmlhttp://www.aygfsteel.com/yongboy/comments/378839.htmlhttp://www.aygfsteel.com/yongboy/archive/2012/05/24/378839.html#Feedback5http://www.aygfsteel.com/yongboy/comments/commentRss/378839.htmlhttp://www.aygfsteel.com/yongboy/services/trackbacks/378839.htmlsocket.io是一種數(shù)據(jù)實(shí)時(shí)推送、事件驅(qū)動(dòng)模型的框架,支持事件訂閱,簡單易用。其價(jià)值目前看來,還未被完整的挖掘出來。

socket.io即提供了node.js服務(wù)器端(地址)又提供了客戶端(地址)的整體解決方案,而socketio-netty則是基于JAVA服務(wù)器端,支持最新socket.io client最新版規(guī)范。對(duì)JAVA編程人員來講,可以不用學(xué)習(xí)node.js,從而多了一個(gè)選擇。  閱讀全文

nieyong 2012-05-24 09:10 發(fā)表評(píng)論
]]>
socketio-netty(socket.io 服務(wù)器端JAVA實(shí)現(xiàn)) 近期升級(jí)手記http://www.aygfsteel.com/yongboy/archive/2012/05/21/378723.htmlnieyongnieyongMon, 21 May 2012 09:31:00 GMThttp://www.aygfsteel.com/yongboy/archive/2012/05/21/378723.htmlhttp://www.aygfsteel.com/yongboy/comments/378723.htmlhttp://www.aygfsteel.com/yongboy/archive/2012/05/21/378723.html#Feedback5http://www.aygfsteel.com/yongboy/comments/commentRss/378723.htmlhttp://www.aygfsteel.com/yongboy/services/trackbacks/378723.html前言

針對(duì)JAVA開發(fā)者,socketio-netty是一個(gè)socket.io的服務(wù)器端選擇,又是目前兼容最新0.9+ – 1.0的JAVA服務(wù)器端實(shí)現(xiàn)。

http://socket.io官網(wǎng)來看,最近版本升級(jí)趨于緩和,幾乎是沒修正一個(gè)Bug,小版本就增加一次。已經(jīng)是非常穩(wěn)定的版本了,可以真正使用了。

貌似國內(nèi)使用socket.io少之又少,可惜了,這么優(yōu)秀的全功能型實(shí)時(shí)推送實(shí)現(xiàn),小眾范圍內(nèi)被知曉。

嗯,就最近當(dāng)前項(xiàng)目修改做一些簡單記載。

 

升級(jí)手記

  1. netty升級(jí)到3.4.5
    3.4.5的QueueFactory類,增加對(duì)了JAVA SE 7引入的JUC并發(fā)類LinkedTransferQueue,若是本地使用JAVA SE 6,還想要保持高性能的阻塞隊(duì)列,那就需要引入Doug Lea’s jsr166y.jar并發(fā)包(下載地址),然后修改一下QueueFactory實(shí)現(xiàn)。我已經(jīng)重新打包成jar包(這里是netty-3.4.5.Final-modify.jar)。
    QueueFactory原始代碼:
    QueueFactory修改后代碼:
  2. socket.io client 升級(jí)到 0.9.6
  3. 支持將HTML/CSS/JS等文件
    socketio.properties 增加配置項(xiàng)static,指定靜態(tài)資源的相對(duì)路徑 ,默認(rèn)是static
    若瀏覽器請(qǐng)求:http://localhost:9000/style/chat.css,則此文件相對(duì)路徑為 static/style/chat.css,其它文件與此類似。
    此屬性便于打包,以及不再單獨(dú)依賴Web容器
    項(xiàng)目中,直接把網(wǎng)頁文件拷貝到/source/static目錄中,運(yùn)行相應(yīng)的JAVA文件(ChatServer.java)
  4. 在Google Code 增加demo
    下載聊天示范,下載后解壓,雙擊 start.bat或者start.sh,瀏覽 http://localhost:9000/ 即可。

有時(shí)間,會(huì)聊聊更具體的實(shí)時(shí)Web一些心得,以及更為具體的示范等。



nieyong 2012-05-21 17:31 發(fā)表評(píng)論
]]>
為Phonegap Android平臺(tái)增加websocket支持,使默認(rèn)成為socket.io首選通道選擇http://www.aygfsteel.com/yongboy/archive/2012/05/10/377787.htmlnieyongnieyongThu, 10 May 2012 06:10:00 GMThttp://www.aygfsteel.com/yongboy/archive/2012/05/10/377787.htmlhttp://www.aygfsteel.com/yongboy/comments/377787.htmlhttp://www.aygfsteel.com/yongboy/archive/2012/05/10/377787.html#Feedback12http://www.aygfsteel.com/yongboy/comments/commentRss/377787.htmlhttp://www.aygfsteel.com/yongboy/services/trackbacks/377787.html嗯,既然是跨瀏覽器平臺(tái),那自然選擇socket.io了。它也是本文的重心,最終目的也是讓socket.io 客戶端版本在Phonegap包裝的Android Apk程序中可以使用Websocket協(xié)議。
同時(shí)也保證我們的示范應(yīng)用盡可能的做到編寫一次,到處運(yùn)行。
還好,有了socket.io(客戶端js) + socketio-netty(socket.io服務(wù)器端JAVA實(shí)現(xiàn)) + Phonegap, 構(gòu)建各種交互的HTML應(yīng)用,是個(gè)不錯(cuò)的選擇。
另,本文項(xiàng)目為僅僅為演示其功能,不保證樣式。  閱讀全文

nieyong 2012-05-10 14:10 發(fā)表評(píng)論
]]>
socketio-netty : 又一款socket.io服務(wù)器端實(shí)現(xiàn),兼容0.9-1.0版本~http://www.aygfsteel.com/yongboy/archive/2012/04/07/373552.htmlnieyongnieyongSat, 07 Apr 2012 14:08:00 GMThttp://www.aygfsteel.com/yongboy/archive/2012/04/07/373552.htmlhttp://www.aygfsteel.com/yongboy/comments/373552.htmlhttp://www.aygfsteel.com/yongboy/archive/2012/04/07/373552.html#Feedback7http://www.aygfsteel.com/yongboy/comments/commentRss/373552.htmlhttp://www.aygfsteel.com/yongboy/services/trackbacks/373552.html 緣起
socket.io是一個(gè)跨瀏覽器的全平臺(tái)反響AJAX實(shí)現(xiàn),官網(wǎng)(http://socket.io)定義為:the cross-browser WebSocket for realtime apps.
個(gè)人認(rèn)為這是一個(gè)跨瀏覽器的集大成者,支持桌面端和移動(dòng)端瀏覽器(http://socket.io/#browser-support):

Desktop

  • Internet Explorer 5.5+
  • Safari 3+
  • Google Chrome 4+
  • Firefox 3+
  • Opera 10.61+

Mobile

  • iPhone Safari
  • iPad Safari
  • Android WebKit
  • WebOs WebKit
為了支持眾多瀏覽器,必然內(nèi)置對(duì)若干協(xié)議的支持:
  • WebSocket
  • Adobe® Flash® Socket
  • AJAX long polling
  • AJAX multipart streaming
  • Forever Iframe
  • JSONP Polling
socket.io跨瀏覽器,根據(jù)瀏覽器自動(dòng)適配最適合方案進(jìn)行實(shí)時(shí)推送。
官方提供了各種語言的實(shí)現(xiàn),見 https://github.com/learnboost/socket.io/wiki/,有java語言實(shí)現(xiàn)服務(wù)器端,但不支持最新的0.9版本,于是萌發(fā)了重寫一個(gè)的想法。

概述

這是一個(gè)Socket.IO服務(wù)器端實(shí)現(xiàn),基于netty框架,適配socket.io 0.9-1.0版本(雖然socket.io 目前還處于 0.9版本,會(huì)支持到1.0)
項(xiàng)目地址: http://code.google.com/p/socketio-netty/
采用流行的Apache License 2.0協(xié)議,svn作為源代碼管理。
郵件討論組為 http://groups.google.com/group/socketio-netty
或者
 https://groups.google.com/group/socketio-netty
期待您的加入。
至于為什么沒有采用tomcat/jetty支持的servlet3規(guī)范、sebsocket實(shí)現(xiàn),個(gè)人認(rèn)為,構(gòu)建在其基礎(chǔ)上較為容易,tomcat7最新版剛剛支持websocket,傳說支持websocket的servlet 3.1還未出世,等等看吧。 而Netty這個(gè)異步IO框架,我們可以在它的基礎(chǔ)上一站式搞定如此多的傳輸通道/協(xié)議。
socketio-netty支持:
  • WebSocket
  • Flash Socket
  • AJAX long polling
  • Forever Iframe
  • JSONP Polling
等傳輸通道協(xié)議。

示范

本示范,參考 socket.io node.js 版本的聊天實(shí)現(xiàn)(chat),客戶端完全一致,服務(wù)器端完全換成了socketio-netty實(shí)現(xiàn)。其它的沒有任何變化。嗯,可能看一個(gè)示范,可以讓人更放心的使用。 客戶端入口 chat.html (存放在tomcat/jetty/nginx/apache/iis相應(yīng)位置,可以直接訪問即可): 看一下,我們的服務(wù)器端如何實(shí)現(xiàn),來一個(gè)啟動(dòng)入口: 然后需要一個(gè)DemoChatHandler處理器,這個(gè)是一個(gè)單列多線程模式:
以上就是整個(gè)的聊天室實(shí)現(xiàn),雖然不算優(yōu)雅,但很簡單。
所有你所需要做的就是,檢出代碼,運(yùn)行com.yongboy.socketio.test.ChatServer即可。


nieyong 2012-04-07 22:08 發(fā)表評(píng)論
]]>
主站蜘蛛池模板: 秭归县| 静宁县| 钟山县| 利津县| 都江堰市| 都兰县| 西林县| 桦南县| 西宁市| 湖北省| 盈江县| 依兰县| 石狮市| 鹤庆县| 合作市| 江阴市| 湘潭县| 中山市| 大姚县| 蒲城县| 乌鲁木齐市| 东平县| 闽清县| 平南县| 壤塘县| 昭平县| 会昌县| 云霄县| 莎车县| 湄潭县| 昌乐县| 大名县| 天门市| 宜兴市| 垣曲县| 滕州市| 连平县| 安新县| 山东省| 上思县| 玉门市|