场景:
你有若干机器,却只有一台能被外网访问,如果要让外网访问到你其它机器上的服务,就需要做反向代理,在上一篇文章中,我们用nodejs轻松实现了http反向代理。如果是TCP服务,例如mysql数据库,同样用nodejs来做实现一个反向代理也是很容易的。
第一种方式:
1var net = require('net'); 2// parse "80" and "localhost:80" or even "42mEANINg-life.com:80" 3var addrRegex = /^(([a-zA-Z\-\.0-9]+):)?(\d+)$/; 4var addr = { 5 from: addrRegex.exec(process.argv[2]), 6 to: addrRegex.exec(process.argv[3]) 7}; 8 9if (!addr.from || !addr.to) { 10 console.log('Usage: <from> <to>'); 11 return; 12} 13 14net.createServer(function(from) { 15 var to = net.createConnection({ 16 host: addr.to[2], 17 port: addr.to[3] 18 }); 19 from.pipe(to); 20 to.pipe(from); 21}).listen(addr.from[3], addr.from[2]);
以上代码存到文件forwarder.js,使用方式:
node forwarder.js 3306 192.168.1.11:3306
第一个参数是本机监听的端口,第二个参数是要转发到目标机器的ip和端口。怎么样,是不是很简单呢。
第二种方式:
1var net = require('net'); 2 3var LOCAL_PORT = 3306; 4var REMOTE_PORT = 3306; 5var REMOTE_ADDR = "192.168.1.11"; 6 7var server = net.createServer(function (socket) { 8 socket.on('data', function (msg) { 9 console.log(' ** START **'); 10 console.log('<< From client to proxy ', msg.toString()); 11 var serviceSocket = new net.Socket(); 12 serviceSocket.connect(parseInt(REMOTE_PORT), REMOTE_ADDR, function () { 13 console.log('>> From proxy to remote', msg.toString()); 14 serviceSocket.write(msg); 15 }); 16 serviceSocket.on("data", function (data) { 17 console.log('<< From remote to proxy', data.toString()); 18 socket.write(data); 19 console.log('>> From proxy to client', data.toString()); 20 }); 21 serviceSocket.on("end", function () { 22 socket.end(); 23 }); 24 }); 25}); 26 27server.listen(LOCAL_PORT); 28console.log("TCP server accepting connection on port: " + LOCAL_PORT);
第一种方式使用了socoket的pipe,第二种相当于自己实现了pipe功能。