導航:首頁 > 編程語言 > nodejs做socket代理

nodejs做socket代理

發布時間:2025-03-05 23:13:56

A. WebSocket 的實現

長連接: 一個鏈接上可以連續發送多個數據包,在鏈接期間,如果沒有數據包發送,需要雙方發鏈路檢查包

TCP/IP: TCP/IP 屬於傳輸層,主要解決網路中的數據傳輸問題,只管傳輸數據。但這樣對傳輸的數據沒有一個規范的封裝、解析等處理。使得傳輸的數據難前咐以識別,所以才有了應用層協議對數據進行的封裝、解析等,如http協議。

HTTP: HTTP協議是慧虛純應用層協議,用於分裝解析傳輸數據。 從HTTP1.1開始其實就默認開啟了長鏈接,也就是請求頭header中可以看到Connection:Keep-alive。但是長連接只是說保持了(伺服器可以告訴客戶端保持時間Keep-Alive:timeout=20;max=20;)這個TCP通道,並採用伺服器和客戶端應答模式(Request-Response),不需要再創建一個鏈接通道,做到一個性能優化。

socket: 與HTTP協議不一樣,socket不是協議,他是在程序層面上對傳輸層協議(像TCP/IP)的介面封裝。我們知道傳輸層的協議,是解決數據在網路中傳輸的問題的,那麼socket(套接字)就是傳輸通道兩端的介面。

Websocket: WebSocket是包裝成了一個應用層協議作為socket,從而能夠讓客戶端和遠程服務端通過web建立全雙工通信。

WebSocket API 是HTML5 推出的東譽悶西。在客戶端我們可以通過HTML5 所提供的API 對websocket 進行創建、發送數據、監聽信息、監聽報錯等功能( HTML5 WebSocket )

我們知道WebSocket 是在Socket的基礎上實現的,所以我們要做的是對現有的Socket協議進行升級

步驟: 客戶端發送websocket請求-->服務端接受並識別該請求-->對該請求協議進行升級--> 返回給客戶端 --> websocket 通道建立 --> 客戶端/服務端發送數據

協議升級

在這里需要注意的是頭部信息和頭部信息中的Sec-Websocket-Accept的值。

該值需要是一個通過base64加密的哈希值(sha1)。 而該加密所用的數據是客戶端傳過來的sec-websocket-key的值和MAGIC_STRINC內的固定值。 對MAGIC_STRINC的說明

Webscoket 中傳輸的數據是 數據幀(frame)

數據幀有多種類型 主要有:文本型、二進制數據

數據幀結構

每一列代表一個位元組,一個位元組8位,每一位又代表一個二進制數。

創建數據幀

解數據幀

心跳檢查

由於websocket 不進行交互會關閉通道所以,才有了心跳檢查。

websocket與和他http的區別

基於node實現websocket協議

使用nodejs在HTTP上實現WebSocket

如何讓我的伺服器返回正確的Sec-WebSocket-Accept標頭值

學習WebSocket協議—從頂層到底層的實現原理

websocket 協議幀 解析

nodejs實現Websocket的數據接收發送

B. nodejshttp不走系統代理

現在使用的代理大部分為HTTP和Socket代理。 Socket代理更底層,需要本地解析域名,而HTTP代理則是基於HTTP協議之上的,不需要本地解析域名。下面我講講HTTP(S)代理的設計思路以及NodeJS代碼實現。
<br/>
<br/><strong>HTTP協議</strong>
<br/>
<br/>HTTP協議簡單說來就是瀏覽器把一串字元串發送到目標伺服器,然後把目標伺服器返回回來的一串字元串顯示給用戶。
<br/>
<br/>瀏覽器發送鏈銀岩的這串字元主要分為兩個部分,一部分是頭,裡麵包含目標伺服器域名,當前請求的文件路徑等信息。另一部分是正文,一般的GET請求沒有正文。
<br/>
<br/>伺服器返回來的字元串也分為頭和正文。
<br/>
<br/><strong>HTTP代理原理</strong>
<br/>
<br/>HTTP代理需要做的事情就是接收瀏覽器發來的請求字元串,再從請求字元串的頭部分找出瀏覽器請求的目標主機,然後直接把這串請求字元串發給目標主機,再把目標主機返回的數據發給瀏覽器。 「什麼?就這么簡單?」 「呃。。是啊,但這還沒完。。」
<br/>
<br/>現代瀏覽器一般都是默認採用HTTP/1.1版本,並且默認會發送Connection: keep-alive請求。 這些信息是寫在請求的頭部的,意思是通知目標伺服器採用keep-alive技術繼續處理後續的請求。 但是我們做的代理程序要想支持keep-alive是比較麻煩的。所以乾脆就把這個篡改成Connection: close。 這樣就可以保證瀏覽器請求的每個文件都會單獨發送一個HTTP請求。
<br/>
<br/><strong>下面是NodeJS代碼實現</strong>
<br/><pre escaped=「true」 lang=「javascript」>var net = require(『net』);
<br/>var local_port = 8893;
<br/>
<br/>//在本地創建一個server監聽本地local_port埠
<br/>net.createServer(function (client)
<br/>{
<br/>
<br/> //首先監聽瀏覽器的數據發送事件,直到收到的數據包含完整的http請求頭
<br/> var buffer = new Buffer(0);
<br/> client.on(『data』,function(data)
<br/> {
<br/> buffer = buffer_add(buffer,data);
<br/> if (buffer_find_body(buffer) == -1) return;
<br/> var req = parse_request(buffer);
<br/> if (req === false) return;
<br/> client.removeAllListeners(『data』);
<br/> relay_connection(req);
<br/> });
<br/>
<br/> //從http請求頭部取得請求信息後,繼續監聽瀏覽器發送數據,同時連接目標伺服器,並把目標伺服器的數據傳給瀏覽器代理的出現是因為瀏覽器同源策略的存在
服務端實現代理的例子和方法很多 比如nginx 反向代理解決生產環境的跨域問題
再有http-server等一些第三方的包幫我處理 基本達到了開箱即用的體驗
通常我們所說的代理來源於http1.1的定義,代理扮演的是「中間人」角色,對於連接到它的客戶端來說,它是服務端;對於要連接的服務端來說,它是棚御客戶端。它就負責在兩端之間來回傳送 HTTP 報文
假如我通過代理訪問A網站,對於A來說,它會把代理當做客戶端,完全察覺不到真正客戶端的存在,這實現了隱藏客戶端IP的目的。
但是他們到底是如何實現的 ,值得一探究竟,下面是用原生nodejs 寫個以後個代理

const http = require("http");
const url = require("url");
//首先啟動本地伺服器
http.createServer(function(req, res) {
//客戶端請求有兩種方式,可以是對象,也可以是url字元串
//1.這里採取的是對象形式,包括url對象以及headers
var options = url.parse(req.url);
options.headers = req.headers;
//2.如果採取字元串形式,就傳入一個完整的url字元串,node會自動解析成url對象

//通過客戶端請求新建一個代理服搏高務器
//代理請求仿照本地請求頭的數據
var proxyRequest = http.request(options, function(proxyResponse) { //代理請求獲取的數據再返回給本地res
proxyResponse.on('data', function(chunk) {
console.log('proxyResponse length:', chunk.length);
res.write(chunk, 'binary');
});
//當代理請求不再收到新的數據,告知本地res數據寫入完畢。
proxyResponse.on('end', function() {
console.log('proxied request ended');
res.end();
});

res.writeHead(proxyResponse.statusCode, proxyResponse.headers);
});

//data只有當請求體數據進來時才會觸發
//盡管沒有請求體數據進來,data還是要寫,否則不會觸發end事件
req.on('data', function(chunk) {
console.log('in request length:', chunk.length);
proxyRequest.write(chunk, 'binary');
});

req.on('end', function() {
//向proxy發送求情,這里end方法必須被調用才能發起代理請求
//所有的客戶端請求都需要通過end來發起
proxyRequest.end();
});

}).listen(8080);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
以上代碼的核心思想就是用http.request充當了中間人的角色 幫我們去目標地址取數據然後在把得到的數據傳回去。可以看作是設計模式中代理模式的一種實踐

C. 如何用websocket+nodejs實現web即時通信服務端

用websocket+nodejs實現web即時通信服務端,Socketio和nodejs配的不錯,建立了socket就可以listen和broadcast。

D. node.js適合做什麼網站

NodeJS的特點:

  1. 它是一個Javascript運行環境

  2. 依賴於Chrome V8引擎進行代碼解釋

  3. 事件驅動

  4. 非阻塞I/O

  5. 輕量、可伸縮,適於實時數據交互應用

  6. 單進程,單線程

NodeJS的缺點:

1. 不適合CPU密集型應用;CPU密集型應用給Node帶來的挑戰主要是:由於JavaScript單線程的原因,如果有長時間運行的計算(比如大循環),將會導致CPU時間片不能釋放,使得後續I/O無法發起;

解決方案:分解大型運算任務為多個小任務,使得運算能夠適時釋放,不阻塞I/O調用的發起;

2. 只支持單核CPU,不能充分利用CPU

3. 可靠性低,一旦代碼某個環節崩潰,整個系統都崩潰

原因:單進程,單線程

解決方案:

(1)Nnigx反向代理,負載均衡,開多個進程,綁定多個埠;

(2)開多個進程監聽同一個埠,使用cluster模塊;

4. 開源組件庫質量參差不齊,更新快,向下不兼容

5. Debug不方便,錯誤沒有stack trace

NodeJS的應用場景:

  1. 實時應用:如在線聊天,實時通知推送等等(如socket.io)

  2. 分布式應用:通過高效的並行I/O使用已有的數據

  3. 工具類應用:海量的工具,小到前端壓縮部署(如grunt),大到桌面圖形界面應用程序

  4. 游戲類應用:游戲領域對實時和並發有很高的要求(如網易的pomelo框架)

NodeJS不適合場景:

CPU使用率較重、IO使用率較輕的應用——如視頻編碼、人工智慧等,Node.js的優勢無法發揮簡單Web應用——此類應用的特點是,流量低、物理架構簡單,Node.js無法提供像Ruby的Rails或者Python的Django這樣強大的框架

閱讀全文

與nodejs做socket代理相關的資料

熱點內容
智能控制webui界面程序 瀏覽:723
臨汾哪裡有學計算機編程 瀏覽:130
qq跳過申訴修改密碼 瀏覽:462
給文件夾加密win10 瀏覽:710
哪個app可以分辨航母 瀏覽:537
哪個app是英英詞典 瀏覽:23
javavoid參數 瀏覽:829
如何讓編程具有記憶功能 瀏覽:435
javamail發送帶附件的郵件 瀏覽:173
微信分享文件到其他軟體 瀏覽:682
微信對話文件夾在哪 瀏覽:287
qq頭像歐美范街頭男生 瀏覽:321
毛孔app 瀏覽:880
照片級渲染教程 瀏覽:304
目錄中的文件夾有什麼用 瀏覽:177
車載u盤文件掃描 瀏覽:410
稻殼文檔怎樣改文件名 瀏覽:620
cad怎麼把文件存成模板 瀏覽:250
編程設計用什麼筆記本流暢 瀏覽:584
電腦突然打開文件很慢 瀏覽:501

友情鏈接