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
,只要合适咱们会当即安排面试。