国产精品高清视亚洲一区二区,久久久久久亚洲精品,亚洲一区二区影视http://www.tkk7.com/yongboy/category/54838.html記錄工作/學習的點點滴滴。zh-cnMon, 01 Jun 2015 04:03:10 GMTMon, 01 Jun 2015 04:03:10 GMT60c_socket.io_server筆記之定義私有接口http://www.tkk7.com/yongboy/archive/2013/03/29/397154.htmlnieyongnieyongFri, 29 Mar 2013 09:18:00 GMThttp://www.tkk7.com/yongboy/archive/2013/03/29/397154.htmlhttp://www.tkk7.com/yongboy/comments/397154.htmlhttp://www.tkk7.com/yongboy/archive/2013/03/29/397154.html#Feedback0http://www.tkk7.com/yongboy/comments/commentRss/397154.htmlhttp://www.tkk7.com/yongboy/services/trackbacks/397154.html有些話說

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

開始實施

以毫無用處的blog為例,簡單兩個方法就行了,需要每一個實現暴露一個可以外部調用函數。

定義一個結構,公用

blog.h:

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

這個頭文件定義了一個對象。可以自由的被包含,包含之后自由使用blog_t結構。

定義一個完全私有函數頭文件

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

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

編寫實現

blog1.c,僅僅一個實現:

#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;
}

僅有一個對外入口:gen_blog1_ptr,也就是此實現對外唯一的交互方式。

blog2.c,默認的實現:

#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;
}

此文件對外唯一入口為:gen_blog2_ptr

其實兩個實現已經可以了,但多一個說明接口單一,實現多樣性,再說錦上添花也是人們喜歡做的事情。 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;
}

一樣可以看到類似約定好的對外函數名稱gen_blog3_ptr

應用端實現

我們以app.c作為應用入口:

#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;
}

這里分別調用blog1.c, blog2.c, blog3.c,唯一入口,執行簡單的邏輯。

編譯運行

編譯命令行代碼很簡單:

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

運行:

./app

運行效果:

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!

小結

這里借助兩個頭文件,模擬了私有接口,公有結構體對象,三個具體子類實現。
c_socket.io_server項目中,作用于具體的實現,以及定義了傳輸通道模型和實現,互相不干擾。
當然和JAVA相比,模擬對象程度稍低了一些,但夠用了。這個世界不僅僅只有面向對象,還有面向并發的函數式Erlang,還有面向軟件工程的大型語言Go。嗯,面向對象不過是這個世界其中一角,天生存在缺陷,也不是被所有人喜歡。組件公用、庫的概念,倒是大部分語言都很自然的欣然接受。面向過程,面向對象,不過是大部分人給與的標簽,怎么用才重要。



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

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

輸出頭部

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

#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服務器中,數據量不大,傳輸內容無須gzip壓縮,畢竟壓縮算法要耗費一些CPU時間。

傳輸部分HTML預備內容

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

#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頭部輸出,剩下內容的輸出,需要注意輸出的簡單格式:

具體輸出內容長度16進制數字表示\r\n具體輸出內容\r\n

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

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

設置定時器,周期性循環

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

時間觸發函數timeout_cb每一秒會定時觸發:

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,基本功能完畢。

編譯運行

編譯一下:

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

運行它:

./htmlfile

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

now time is 1364043695

完整代碼



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

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

長輪詢

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

輸出頭部

一般優先輸出頭部,告訴瀏覽器,需要保持長連接,當然,這需要瀏覽器支持http 1.1協議,并且明確的注明當前連接為一直保持著: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);

定時器啟動,等待

連接什么時候關閉,需要在代碼中手動控制,除非瀏覽器端在發出請求等待響應期間出現異常,無故斷開了連接。設服務器端設定好連接持續時間為30秒,那么就應該啟動一個定時器,除非所使用的語言層面提供了內置支持。

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

定時器start之后,觸發的函數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     }

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


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

編譯運行

編譯一下:

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

運行它:

./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秒后輸出具體的文字內容:

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

小結

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

完整代碼



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

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

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

預備知識

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

處理靜態文件

這里設計一個靜態文件WEB服務器,非常簡單,僅僅滿足socket.io服務器最基本的需求,因此別苛求太多。但比網上很多大把類似文章多了一點寫入管道時緩沖區已滿問題的處理。
這里簡單說一下處理靜態文件的思路。

計算靜態文件路徑以及擴展名和內容類型

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

獲取文件內容和以及優先輸出響應頭部

    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頭部文件,調用fstat初始化stat結構,可判斷文件是否存在,以及文件大小等。

讀取文件內容到緩沖區,循環寫入

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);

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

關閉socket描述符,當前請求結束

free_res(loop, client);

請求完成,一定要記得關閉socket描述符,釋放相應資源等。 這樣一個較為完整的HTTP請求,靜態文件就處理完畢了。

編譯運行

先編譯:

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

運行之:

./static_server ../static

命令輸入錯誤,如輸入靜態路徑為空,會報錯的,哈哈:

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

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

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



nieyong 2013-03-25 16:46 發表評論
]]>
哈,又來一個純C語言版本的socket.io服務器端實現~http://www.tkk7.com/yongboy/archive/2013/03/15/396493.htmlnieyongnieyongFri, 15 Mar 2013 08:02:00 GMThttp://www.tkk7.com/yongboy/archive/2013/03/15/396493.htmlhttp://www.tkk7.com/yongboy/comments/396493.htmlhttp://www.tkk7.com/yongboy/archive/2013/03/15/396493.html#Feedback1http://www.tkk7.com/yongboy/comments/commentRss/396493.htmlhttp://www.tkk7.com/yongboy/services/trackbacks/396493.html前言

哈,這又是一個socket.io服務端實現,本意是,拿C練練手,加強對C和linux系統的理解,寫著寫著,就寫成了一個socket.io服務器端實現了。以為半成品,那就正式托管在github站點上吧,以便記錄一下,可讓大家批評與指正,加強內功的修煉等。
項目地址為
yongboy/c_socket.io_server

以下部分文字,偷懶,摘錄自項目的README.md文件

說明

這是一個純C語言版本的socket.io服務器端實現,目前僅支持linux系統,嚴重依賴libev and glib等基礎庫。
在運行socket.io_server之前,需要安裝以下依賴:

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

如何運行

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

API說明

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

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

其它

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



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

最近在學習Erlang,順便寫了一個socket.io server作為練練手,感受函數式/面向并發編程的好處。

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

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

mochiweb,有些歷史,已趨于穩定,但目前不支持websocket協議。

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

閑話少說,目前已經釋出0.1版本,項目地址為:

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

項目介紹

Erlang 版本的socket.io服務器實現

1. 基于cowboy構建

檢出地址: 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等通訊協議
支持CJK語言,UTF-8編碼下很少出現亂碼
現在可以作為0.1版本釋出,具有一個chat示范

2. 基于mochiweb構建

檢出地址: 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等通訊協議
暫時精力有限,停止更新,假若有需要,可以進一步有償商談

3. 運行一個示范

一個實現

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

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

其它

剛入門,項目代碼寫的有些草;您若慷慨,希望給些指點,謝謝 :))



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

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

構建一個最簡單的EventBus javascript庫,也不難:

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

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

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

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



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

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

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

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

針對JAVA開發者,socketio-netty是一個socket.io的服務器端選擇,又是目前兼容最新0.9+ – 1.0的JAVA服務器端實現。

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

貌似國內使用socket.io少之又少,可惜了,這么優秀的全功能型實時推送實現,小眾范圍內被知曉。

嗯,就最近當前項目修改做一些簡單記載。

 

升級手記

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

有時間,會聊聊更具體的實時Web一些心得,以及更為具體的示范等。



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

nieyong 2012-05-10 14:10 發表評論
]]>
socketio-netty : 又一款socket.io服務器端實現,兼容0.9-1.0版本~http://www.tkk7.com/yongboy/archive/2012/04/07/373552.htmlnieyongnieyongSat, 07 Apr 2012 14:08:00 GMThttp://www.tkk7.com/yongboy/archive/2012/04/07/373552.htmlhttp://www.tkk7.com/yongboy/comments/373552.htmlhttp://www.tkk7.com/yongboy/archive/2012/04/07/373552.html#Feedback7http://www.tkk7.com/yongboy/comments/commentRss/373552.htmlhttp://www.tkk7.com/yongboy/services/trackbacks/373552.html 緣起
socket.io是一個跨瀏覽器的全平臺反響AJAX實現,官網(http://socket.io)定義為:the cross-browser WebSocket for realtime apps.
個人認為這是一個跨瀏覽器的集大成者,支持桌面端和移動端瀏覽器(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
為了支持眾多瀏覽器,必然內置對若干協議的支持:
  • WebSocket
  • Adobe® Flash® Socket
  • AJAX long polling
  • AJAX multipart streaming
  • Forever Iframe
  • JSONP Polling
socket.io跨瀏覽器,根據瀏覽器自動適配最適合方案進行實時推送。
官方提供了各種語言的實現,見 https://github.com/learnboost/socket.io/wiki/,有java語言實現服務器端,但不支持最新的0.9版本,于是萌發了重寫一個的想法。

概述

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

示范

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


nieyong 2012-04-07 22:08 發表評論
]]>
主站蜘蛛池模板: 国产午夜亚洲精品不卡| 亚洲人成777在线播放| 免费观看黄网站在线播放| 黄色成人网站免费无码av| 亚洲香蕉免费有线视频| 99久9在线|免费| 99久久亚洲综合精品成人网| 野花香高清视频在线观看免费| 曰批全过程免费视频播放网站| 国产福利免费观看| 特级精品毛片免费观看| 亚洲啪啪AV无码片| 亚洲免费视频网站| 亚洲人成片在线观看| 四虎成人免费网址在线| 四虎影院免费在线播放| 亚洲人成自拍网站在线观看| 国产免费一级高清淫曰本片 | 国产成人高清亚洲| 亚洲国产亚洲综合在线尤物| 91免费资源网站入口| 亚洲熟女综合色一区二区三区 | 亚洲精品自拍视频| 97人妻无码一区二区精品免费| 99久久免费国产精品特黄| 亚洲一卡一卡二新区无人区| 麻豆国产人免费人成免费视频 | 亚洲国产成人久久精品动漫 | 国产亚洲精品自在久久| 在线视频亚洲一区| 中国亚洲女人69内射少妇| 久久国产精品萌白酱免费| 日韩精品亚洲aⅴ在线影院| 亚洲一区二区三区成人网站 | 国产免费啪嗒啪嗒视频看看| 亚洲成A人片在线观看中文| 国产av无码专区亚洲av毛片搜| 国产日韩一区二区三免费高清| 国产色爽免费视频| 国产免费A∨在线播放| 午夜免费1000部|