39

node.js创建aria2代理服务器:使用net.socket转发rpc或http request请求,替换websocke...

 4 years ago
source link: http://ourjs.com/detail/k88hx59pggps
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Aria2是一款免费开源跨平台且不限速的多线程下载软件,目前很多NAS用它来搭建下载服务器。

WebSocket连RPC

Aria2 BT下载可通过网页端访问,网页站通过RPC与Aria程序通讯。

RPC(Remote Procedure Call)是远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。目前有很多软件支持这种协议。

Aria2通过websocket来调用aria2的rpc服务,实现状态查询、创建下载任务,这样可以解决ajax的跨域问题。不过这样NAS服务器要新开一个端口,而且旧浏览器并不支持,并且权限控制也很不方便。此时可使用代理服务器,在代理服务器中添加更多业务逻辑。

Socket代理

用Socket创建代理转发服务非常简单,下面这段代码侦听9000端口,有连接进来时创建一个socket连接aria2的rpc服务,然后将数据转发过去。

因为socket是异步的,如果代理服务器连的不是本机的,则一定要暂停请求的socket,等连接建立时再恢复接收数据:

socket.resume()
socket.pause()

详细代码

const net = require('net')
const Socket = net.Socket
const server = net.createServer(function(socket) {
 console.log(socket.address())

 var client = new Socket()

 var endHandler = function() {
 console.log('client end')
 }

 var dataHandler = function(chunk) {
 console.log('client receive')
 console.log(chunk.toString())
 socket.write(chunk)
 }

 var errHandler = function() {
 console.trace('client error', arguments)
 }

 console.log('connect 127.0.0.1:6800')
 client.connect(6800, '127.0.0.1', function() {
 console.log('client connected')
 socket.resume()
 })

 client.on('data', dataHandler)
 client.on('end', endHandler)
 client.on('timeout', errHandler)
 client.on('error', errHandler)


 /*
 proxy
 */
 socket.pause()

 var onClose = function() {
 var socket = this
 console.log('onClose')
 }

 var onConnect = function() {
 var socket = this
 console.log('onConnect')
 }

 var onData = function(chunk) {
 console.log('onData and send to client')
 console.log(chunk.length)
 client.write(chunk)
 }

 var onEnd = function() {
 console.log('on end')
 }

 var onError = function() {
 console.trace('on error')
 }

 var onLookup = function() {
 console.log('on lookup')
 }

 var onTimeout = function() {
 console.log('on onTimeout')
 }

 var onDrain = function() {
 console.log('on drain', arguments)
 }

 socket.on('close', onClose)
 socket.on('connect', onConnect)
 socket.on('data', onData)
 socket.on('drain', onDrain)
 socket.on('end', onEnd)
 socket.on('error', onError)
 socket.on('lookup', onLookup)
 socket.on('timeout', onTimeout)
})

server.on('error', function(err) {
 console.error('proxy error', new Date(), err)
})

server.on('listening', function() {
 console.log('proxy listening', arguments)
})

server.listen(9000, function() {
 console.log('server started', server.address())
})

使用ajax连PRC

RPC是支持http调用的,因此可以在node.js网页服务器上创建一个http代理转发服务。这样能够使用统一的session权限管理。

rpc要接收http原始请数据才能判断此请求是基于http的,这里通过getRawData来拼接header和post body实现。

var getRawData = function(req) {
 var raw = req.method + ' ' + req.url + ' HTTP/1.1'
 for (var i = 0; i < req.rawHeaders.length; i+=2) {
 raw += '\r\n' + req.rawHeaders[i] + ': ' + req.rawHeaders[i+1]
 }

 if (req.body) {
 raw += '\r\n\r\n' + req.body
 }

 return raw
}

app.post('/jsonrpc2', function(req, res) {
 var content = getRawData(req)
 request({
     url : 'http://127.0.0.1:6800/jsonrpc'
   , data : req.body
 }, function(err, response, data) {
   if (err) {
     console.log(err)
     res.send(err.toString())
     return
   }

   res.send(data)
 })
}, { post: 'raw' })

参考*

request 代码请见: 用node.js实现http网页爬虫抓取,模拟ajax\post请求 

本例使用的是 onceio 框架实现,也可使用Express实现,代码类似


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK