UNPKG

request-pool-beta

Version:

An intelligent proxy and request manager.

176 lines (133 loc) 5.13 kB
var request=require('request'); var cheerio=require('cheerio'); export interface IServerState{ alive:boolean; total:number; fail:number; last:number; } export interface IRequestCallback{ (err:any,res:any,body:string):void; } export interface IRequest{ url:string; callback:IRequestCallback; } export interface IInitCallback{ (GetHandler:IHandler) } export interface IHandler{ Get:IGetHandler; AddProxy:IAddProxyHandler; } export interface IGetHandler{ (url:string,callback:IRequestCallback):void; } export interface IAddProxyHandler{ (address:string):void; } export class RequestPool{ private ServerTimeout:number=3000; private ServerInterval:number=1000; private ServerList:Map<string,number>=new Map<string,number>(); private ServerState:Map<string,IServerState>=new Map<string,IServerState>(); private ServerAvailable:Array<string>=[]; private ServerUsed:Array<string>=[]; private ServerToCheck:Array<string>=[]; private RequestQueue:Array<IRequest>=[]; private HighPriorityQueue:Array<IRequest>=[]; private Handler:any; constructor(){ } public Init(callback:IInitCallback):void{ var base=this; function Get(url:string,callback:IRequestCallback):void{ base.RequestQueue.unshift({url:url,callback:callback}); } function AddProxy(address:string){ if(base.ServerList[address]==undefined){ base.ServerList[address]=1; var state:IServerState={ alive:false, total:0, fail:0, last:0 } base.ServerState[address]=state; base.ServerToCheck.unshift(address); } } function StartService(service:Function,interval:number){ setInterval(service, interval); } //Service:CheckServer function Service_CheckServer():void{ if(base.ServerToCheck.length>0){ base.ServerToCheck.forEach(function(addr){ request("http://www.baidu.com",{proxy:addr,timeout:base.ServerTimeout},function(err,res,body){ if(!err&&res.statusCode==200){ base.ServerUsed.unshift(addr); } }) }) base.ServerToCheck=[]; } } //---Service //Service:ExecuteRequest function Service_ExecuteRequest():void{ if(base.ServerAvailable.length>0){ //Have requests and available servers var req:IRequest; if(base.HighPriorityQueue.length>0){ req=base.HighPriorityQueue.pop();//get element from right of the queue } else if(base.RequestQueue.length>0) req=base.RequestQueue.pop(); else return;//no requests to execute var addr=base.ServerAvailable.pop(); var url=req.url; var cb=req.callback; request(url,{proxy:addr,timeout:base.ServerTimeout},function(err,res,body){ if(err=='ETIMEDOUT'||body==undefined){//have some error if(err!='ETIMEDOUT')//server unstable but not dead base.ServerUsed.unshift(addr); else{ //server is dead //give up this server } base.HighPriorityQueue.unshift(req);//push in left } else{ //success base.ServerState['last']=Date.now(); base.ServerUsed.unshift(addr); cb(err,res,body); } }) } } //---Service //Service:ServerInterval function Service_ServerInterval():void{ for(var i=0;i<base.ServerUsed.length;i++){ var addr=base.ServerUsed[base.ServerUsed.length-1]; var last=base.ServerState[addr]['last']; if(Date.now()-last>base.ServerInterval){ base.ServerUsed.pop(); base.ServerAvailable.unshift(addr); } else return; } } //---Service setInterval(Service_CheckServer,1000); setInterval(Service_ExecuteRequest,50); setInterval(Service_ServerInterval,200); //GetProxy var handler:IHandler={Get:Get,AddProxy:AddProxy} callback(handler); } }