whistle v1.6.0
(Github地址:https://github.com/avwo/whistle) 開始支持WebSocket和通常Socket的抓包、構造請求、以及修改發送或接收的數據。html
打開whistle的Network,選中左側請求列表中的WebSocket(Socket)請求,點擊右側的 Response -> Frames
。前端
WebSocket抓包:git
Socket(TCP)請求,須要通過Tunnel代理鏈接whistle,再經過whistle轉發,未避免whistle把普通Socket請求當成https或websocket請求,須要代理請求頭添加個字段 x-whistle-policy: tunnel
,下面以Node爲例說明如何經過whistle轉發Socket(TCP)請求(其它語言同理:先發一個http請求給whistle代理把請求信息帶給whistle,whistle請求目標服務器成功後把鏈接返回):github
模擬後臺Socket Server代碼:web
const net = require('net'); const server = net.createServer(); server.on('connection', (client) => { client.on('error', () => {}); client.on('data', (data) => { client.write(`Response: ${data}`); }) }); server.listen(9999);
客戶端代碼:面試
const http = require('http'); const net = require('net'); // whistle監聽端口,根據實際狀況設定 const PROXY_PORT = 8899; // whistle所在服務器IP const PROXY_HOST = '127.0.0.1'; // 鏈接whistle代理 const connect = (options) => { options = { method: 'CONNECT', host: PROXY_HOST, port: PROXY_PORT, path: `${options.host}:${options.port}`, agent: false, headers: { 'x-whistle-policy': 'tunnel', // 必填,不然沒法查看抓包數據 } }; return new Promise((resolve, reject) => { const client = http.request(options); client.once('connect', (req, socket) => resolve(socket)); client.once('error', reject); client.end(); }); }; const init = async () => { const options = { host: '127.0.0.1', port: 9999 }; const socket = await connect(options); let index = 0; const send = () => { ++index; socket.write(`${index}. This is a JSON Object: {"test": "index=${index}"}`); }; socket.on('data', (data) => { setTimeout(send, 3000); }); send(); }; init().catch(err => { throw err; });
在Network的右側Composer能夠構造各類請求,包括http、https、WebSocket、Socket請求,能夠直接填寫要請求的url、方法、請求頭、請求內容等,也能夠直接從左側列表把對應的數據拖過來。npm
以WebSocket Demo網站爲例(http://demos.kaazing.com/echo/),創建以下鏈接,併發送數據(用Composer構造的WebSocket在Frames下面會出現一個Composer選項,用於向Server發送數據,也能夠經過直接上傳文件發送):服務器
GET /echo HTTP/1.1 WebSocket-Protocol: Sec-WebSocket-Protocol: Sec-WebSocket-Extensions: x-kaazing-idle-timeout,x-kaazing-ping-pong,x-kaazing-http-revalidate 1
後面經過Frames裏面的Composer發送什麼數據後臺就返回什麼:websocket
通常Socket請求只需把請求方法改成 CONNECT
,或者用這些協議的url conn://
、connect://
、socket://
、、tunnel://
:weex
從上面的插圖能夠發現,若是請求不是經過whistle的Composer發送的,WebSocket和Socket請求都沒法添加或修改接收及發送數據(Composer創建的鏈接能夠發送數據到服務端),要修改WebSocket或Socket的發送或接收數據,須要藉助whistle的插件whistle.script,其原理是經過配置whistle規則把請求轉發到whistle.script裏面的WebSocket或Socket服務器,再經過whistle.script攔截或發送到指定後臺。
npm i -g whistle.script # 或 npm i -g whistle.script --registry=https://registry.npm.taobao.org
調試WebSocket請求,打開插件script的界面http://local.whistlejs.com/whistle.script/,新建名爲handleWebSocket的script:
exports.handleWebSocket = async (ws, connect) => { // 將請求繼續轉發到目標後臺,若是不加則直接響應 const res = await connect(); // 獲取客戶端的請求數據 ws.on('message', (data) => { // 在script的Console打印出客戶端發送的數據 console.log(`Client: ${data}`); // 能夠修改後再發送到Server res.send(data); }); res.on('message', (data) => { // 在script的Console打印出服務端發送的數據 console.log(`Server: ${data}`); // 能夠修改後再發送到Server ws.send(data); }); // 接收經過whistle.script頁面Console的dataSource.emit('toSocketClient', {name: 'toSocketClient'})的數據 ws.dataSource.on('toSocketClient', (data) => { ws.send(data); }); // 接收經過whistle.script頁面Console的dataSource.emit('toSocketServer', {name: 'toSocketClient'})的數據 ws.dataSource.on('toSocketServer', (data) => { res.send(data); }); };
在whistle上配置規則:
ws://demos.kaazing.com/echo script://handleWebSocket
打開http://demos.kaazing.com/echo/,點擊 Connect
按鈕:
調試Socket請求,同上操做在whistle.script插件上新建一個名爲 handleSocket
的腳本:
exports.handleTunnel = async (client, next) => { // 將請求繼續轉發到目標後臺,若是不加則直接響應 const res = await next(); // 獲取客戶端的請求數據 client.on('data', (data) => { // 在script的Console打印出客戶端發送的數據 console.log(`Client: ${data}`); // 修改後再發送到Server res.write(`Client>>>Server: ${data}+client`); }); res.on('data', (data) => { // 在script的Console打印出服務端發送的數據 console.log(`Server: ${data}`); // 修改後再發送到Server client.write(`Server>>>Client: ${data}`); }); // 接收經過whistle.script頁面Console的dataSource.emit('toSocketClient', {name: 'toSocketClient'})的數據 client.dataSource.on('toSocketClient', (data) => { client.write(JSON.stringify(data)); }); // 接收經過whistle.script頁面Console的dataSource.emit('toSocketServer', {name: 'toSocketClient'})的數據 client.dataSource.on('toSocketServer', (data) => { res.write(JSON.stringify(data)); }); };
在whistle上配置規則:
127.0.0.1:9999 script://handleSocket
啓動文章剛開始的Socket鏈接的例子,打開whistle.script界面的Console,在裏面分別執行下面兩個語句:
dataSource.emit('toSocketClient', 'Mock Server'); dataSource.emit('toSocketServer', 'Mock Client');
whistle.script會把對應的事件名稱及參數值傳給後臺 ctx.dataSource
的對應監聽方法。
騰訊在線教育部前端團隊急招大量優秀前端開發(Node、React、RN、Vue、weex等方面的人才,無論全棧仍是隻專一某個領域的均可以,瞭解職位信息點擊這裏),這邊各方面(你懂的)在業界都是至關有競爭力,考慮你們年末換工做可能拿不到年終獎,老闆說了入職後這邊都會給相應的補償,因此這點不須要太擔憂,有想換工做的或者追求更好發展平臺把簡歷發我郵箱 avwu@qq.com
,只要合適咱們會當即安排面試。