這篇文章主要介紹“nginx websocket有什么特點(diǎn)”,在日常操作中,相信很多人在nginx websocket有什么特點(diǎn)問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”nginx websocket有什么特點(diǎn)”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!
創(chuàng)新互聯(lián)建站-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比肥城網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式肥城網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋肥城地區(qū)。費(fèi)用合理售后完善,十載實(shí)體公司更值得信賴。
websocket是基于TCP的應(yīng)用層協(xié)議,用于在C/S架構(gòu)的應(yīng)用中實(shí)現(xiàn)雙向通信,rfc文檔說明rfc6455。
websocket在建立連接時(shí)會(huì)使用HTTP協(xié)議,所以websocket協(xié)議是基于HTTP協(xié)議實(shí)現(xiàn)的。
目前很多卡牌類的游戲選擇使用websocket協(xié)議進(jìn)行通信。
websocket具備如下特點(diǎn):
1.可以進(jìn)行雙向通信,會(huì)話通信實(shí)時(shí)性強(qiáng)。
2.建立起websocket連接,可以一直保持連接,在此期間可以源源不斷的發(fā)送消息,直到關(guān)閉請(qǐng)求。避免了HTTP的非狀態(tài)性(連接時(shí)總開銷減少)。和http相比連接創(chuàng)建后,客戶端服務(wù)端進(jìn)行數(shù)據(jù)交換時(shí),協(xié)議控制的數(shù)據(jù)包頭部較小(通信量減少)。
3.web服務(wù)器與客戶端之間建立起連接后,所有的通信都依靠這個(gè)專用協(xié)議進(jìn)行。通信過程中可互相發(fā)送JSON、XML、HTML或圖片等任意格式的數(shù)據(jù)。不論服務(wù)器還是客戶端,任意一方都可直接向?qū)Ψ桨l(fā)送數(shù)據(jù)。
4.更好的二進(jìn)制支持,支持?jǐn)U展。
websocket協(xié)議格式:
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-------+-+-------------+-------------------------------+ |F|R|R|R| opcode|M| Payload len | Extended payload length | |I|S|S|S| (4) |A| (7) | (16/64) | |N|V|V|V| |S| | (if payload len==126/127) | | |1|2|3| |K| | | +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + | Extended payload length continued, if payload len == 127 | + - - - - - - - - - - - - - - - +-------------------------------+ | |Masking-key, if MASK set to 1 | +-------------------------------+-------------------------------+ | Masking-key (continued) | Payload Data | +-------------------------------- - - - - - - - - - - - - - - - + : Payload Data continued ... : + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | Payload Data continued ... | +---------------------------------------------------------------+
在使用nginx開啟websocket配置時(shí),可以通過在server{}塊中配置websocket配置。
server { listen 80; server_name www.domain.com; location / { proxy_pass http://127.0.0.1:8080/; //回源地址 proxy_http_version 1.1; proxy_read_timeout 600s; //超時(shí)設(shè)置 //啟用支持websocket proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }
如上配置它表明websocket請(qǐng)求連接的時(shí)候,升級(jí)連接將http連接變成websocket連接。
但這里會(huì)有一個(gè)問題,這樣在server{}塊中配置websocket,該server{}必須處理websocket流量,所有發(fā)往后端的流量都帶上upgrade和connection頭。
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
在server{}中配置websocket時(shí),所有發(fā)往后端upstream的流量會(huì)添加websocket頭。
假如發(fā)往后端upstream的請(qǐng)求,有的需要添加websocket頭升級(jí)為websocket,有的請(qǐng)求不需要,如果繼續(xù)使用原生的nginx配置,會(huì)導(dǎo)致該場(chǎng)景該配置,出現(xiàn)問題。
所以該場(chǎng)景下需改動(dòng)和優(yōu)化nginx源碼,來區(qū)分client的流量是否是websocket。
ngx_http_proxy_websocket_headers:區(qū)別在于connection和upgrade
static ngx_keyval_t ngx_http_proxy_websocket_headers[] = { { ngx_string("Host"), ngx_string("$proxy_host") }, { ngx_string("Connection"), ngx_string("Upgrade") }, { ngx_string("Content-Length"), ngx_string("$proxy_internal_body_length") }, { ngx_string("Transfer-Encoding"), ngx_string("$proxy_internal_chunked") }, { ngx_string("TE"), ngx_string("") }, { ngx_string("Keep-Alive"), ngx_string("") }, { ngx_string("Expect"), ngx_string("") }, { ngx_string("Upgrade"), ngx_string("websocket") }, { ngx_null_string, ngx_null_string } }; #ifdef NGX_WEBSOCKET_INNER // 通過headers來init rc = ngx_http_proxy_init_headers(cf, conf, &conf->websocket_headers, ngx_http_proxy_websocket_headers); if (rc != NGX_OK) { return NGX_CONF_ERROR; } #endif static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { ... // 獲取upgrade標(biāo)志 if (ngx_strcasestrn(h->value.data, "Upgrade", 7 - 1)) { r->is_websocket_request |= NGX_WEBSOCKET_HEADER_CONNECTION; } ... } if (r->headers_in.upgrade == NULL) { goto not_websocket_request; } else if ((r->is_websocket_request & NGX_WEBSOCKET_HEADER_CONNECTION) == 0) { goto not_websocket_request; // } else if (ngx_strncasecmp(r->headers_in.upgrade->value.data, (u_char *)"websocket", 9) == 0) { // 判斷是否含有websocket,添加標(biāo)志 } else if (ngx_strcasestrn(r->headers_in.upgrade->value.data, "websocket", 9 - 1)) { r->is_websocket_request |= NGX_WEBSOCKET_HEADER_UPGRADE; } // 兩種標(biāo)志都有,r->websocket_request 標(biāo)志位置位 if (r->is_websocket_request == (NGX_WEBSOCKET_HEADER_UPGRADE | NGX_WEBSOCKET_HEADER_CONNECTION)) { r->websocket_request = 1; r->http_version = NGX_HTTP_VERSION_11; } else { r->websocket_request = 0; } ngx_http_proxy_process_header配置upstream的標(biāo)志位 static ngx_int_t ngx_http_proxy_process_header(ngx_http_request_t *r) { ... if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS) { u->keepalive = 0; if (r->headers_in.upgrade) { u->upgrade = 1; } } ... } 在ngx_http_upstream_send_response種使用該標(biāo)志位 static void ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) { ... if (u->upgrade) { ngx_http_upstream_upgrade(r, u); return; } ... } ngx_http_upstream_upgrade給上下游設(shè)置讀寫事件 static void ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u) { ... u->read_event_handler = ngx_http_upstream_upgraded_read_upstream; u->write_event_handler = ngx_http_upstream_upgraded_write_upstream; r->read_event_handler = ngx_http_upstream_upgraded_read_downstream; r->write_event_handler = ngx_http_upstream_upgraded_write_downstream; ... } 每個(gè)讀寫時(shí)間所用的函數(shù)都是一樣的,入?yún)⒉煌?from_upstream代表是否是后端,do_write代表是否是寫事件 下面以u(píng)pstream的讀事件為例 static void ngx_http_upstream_process_upgraded(ngx_http_request_t *r, ngx_uint_t from_upstream, ngx_uint_t do_write) { ... // from_upstream為1,src為upstream(上游),dst為downstream(下游) if (from_upstream) { src = upstream; dst = downstream; b = &u->buffer; } for ( ;; ) { // do_write為0忽略。 if (do_write) {} if (size && src->read->ready) { // src為upstream,用來讀 n = src->recv(src, b->last, size); // n >0 接收大于0的字節(jié)數(shù),do_write置為1,continue進(jìn)行寫入 if (n > 0) { do_write = 1; b->last += n; if (from_upstream) { u->state->bytes_received += n; } continue; } // 加入三個(gè)計(jì)時(shí)器,upstream讀寫都加,downstream只加寫入,相當(dāng)于除了client的接收沒加計(jì)時(shí)器,都加了 if (upstream->write->active && !upstream->write->ready) { ngx_add_timer(upstream->write, u->conf->send_timeout); } else if (upstream->write->timer_set) { ngx_del_timer(upstream->write); } if (upstream->read->active && !upstream->read->ready) { ngx_add_timer(upstream->read, u->conf->read_timeout); } else if (upstream->read->timer_set) { ngx_del_timer(upstream->read); } if (downstream->write->active && !downstream->write->ready) { ngx_add_timer(downstream->write, clcf->send_timeout); } else if (downstream->write->timer_set) { ngx_del_timer(downstream->write); } ... }
到此,關(guān)于“nginx websocket有什么特點(diǎn)”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!
網(wǎng)頁題目:nginxwebsocket有什么特點(diǎn)
URL地址:http://aaarwkj.com/article30/gihspo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營(yíng)銷推廣、標(biāo)簽優(yōu)化、用戶體驗(yàn)、品牌網(wǎng)站設(shè)計(jì)、定制網(wǎng)站、企業(yè)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)