簡體   English   中英

在長時間輪詢中添加了node.js超時

[英]node.js timeouts get added up in long polling

我將以下內容用於基本的長輪詢:

var http = require('http');
var url = require('url');
var Memcached = require('memcached');
var libAS = require('./libAS');
var cache = new Memcached('localhost:11211');

http.createServer(function(request,response) {
    response.writeHead(200, { 'Content-Type': 'text/plain' , 'Access-Control-Allow-Origin' : 'http://localhost'});
    var url_parts = url.parse(request.url,true);
    var querystring = url_parts.query;

    if(!libAS.exists(querystring.channel_id) || !libAS.exists(querystring.workstamp) || !libAS.exists(querystring.subscriber))
    {
        response.end("Invalid Request");
    }

    var channel = new Channel(querystring.channel_id,cache);
        //get workstamp
        channel.getWorkstamp(function(workstamp) {
        if(!workstamp)
        {
            //If workstamp not found
            response.end("Channel invalid");
        }
        else
        {
            channel.checkSubscriber(querystring.subscriber,function(valid) {
                if(!valid)
                {
                    response.end("Channel invalid");
                }
                else
                {
                    channel.startLoop(querystring.workstamp,response);
                }
            });
        }
                });
}).listen(1111,'localhost');

//----------------------------------CHANNEL HANDLING----------------------------------------//

var Channel = function(id,cache) {
    this.cache = cache;
    this.id = id;
    this.loopLimit = 10; // Almost equal to seconds.
    this.loopCount = 0;
    this.WSDump = null;

    this.getWorkstamp(function(workstamp){
        this.WSDump = workstamp;
    });

};

Channel.prototype.startLoop = function(workstamp,response) {
    _self = this;
    _self.WSDump = workstamp;
        _self.checkUpdates(workstamp,function(updated,current_workstamp){
            if(updated)
            {
                console.log("Updated. Ending");
            }
            else
            {
                if(_self.loopCount<_self.loopLimit)
                {
                    console.log("Not Updated. Continuing with workstamp "+current_workstamp);
                    _self.loopCount++;
                    _self.loop(current_workstamp,response);
                }
                else
                {
                    console.log("Limit reached. Updating current workstamp "+current_workstamp);
                    _self.endResponse(200,response);
                }
            }
        });
};

Channel.prototype.loop = function(workstamp,response) {
    _self = this;
    _self.WSDump = workstamp;
    setTimeout(function() {
        _self.checkUpdates(workstamp,function(updated,current_workstamp){
            if(updated)
            {
                console.log("Updated. Ending");
            }
            else
            {
                if(_self.loopCount<_self.loopLimit)
                {
                    console.log("Not Updated. Continuing with workstamp "+current_workstamp);
                    _self.loopCount++;
                    _self.loop(current_workstamp,response);
                }
                else
                {
                    console.log("Limit reached. Updating current workstamp "+current_workstamp);
                    _self.endResponse(200,response);
                }
            }
        });
    },1000);
};

Channel.prototype.endResponse = function(code,response) {
    if(code === 200)
    {
        json = {"status":200};
    }
    response.end(JSON.stringify(json));
};

Channel.prototype.checkUpdates = function(workstamp,callback) {
    this.getWorkstamp(function(current_workstamp) {
        if(!current_workstamp) callback(false);
        else
        {
            if(workstamp == current_workstamp)
            {
                callback(false,current_workstamp);
            }
            else
            {
                callback(true,current_workstamp);
            }
        }
    });
};

Channel.prototype.getWorkstamp = function(callback) {
    this.cache.get(this.id+':channel'+':workstamp',function(err,data){
        if(err)
        {
            console.log(err);
            callback(false);
        }
        else
        {
            callback(data);
        }
    });
};

Channel.prototype.checkSubscriber = function(id,callback) {
    this.cache.get(this.id+':channel:subscriptions',function(err,data) {
        if(err)
        {
            console.log(err);
            callback(false);
        }
        else
        {
            data = getArray(data);
            for(i=0;i<data.length;i++)
            {
                if(data[i]['id']==id)
                {
                    callback(true);
                    break;
                }
                else
                {
                    if(i == (data.length-1))
                    {
                        callback(false);
                        break;
                    }
                }
            }
        }
    });
};

Channel.prototype.fetch = function(callback) {
    this.cache.get(this.id+':channel',function(err,data){
        if(err)
        {
            console.log(err);
            callback(false);
        }
        else
        {
            callback(getArray(data));
        }
    });
};

var getArray = function(obj) {
    return JSON.parse(obj.toString());
};

當僅連接1個客戶端時,即按10秒鍾結束過程,此操作將按照我的意願運行。 但是,當我同時通過2個客戶端發送請求時,過程將在20秒鍾后結束。 如果為3,則為30s。 有人可以告訴我這個問題嗎? 我以為每個請求都會分別執行相同的代碼? (PS,我不太擅長javascript,對於未記錄的代碼我深表歉意,我有點着急)。

解決了。 循環計數在某處混淆的位置。 我對其進行了更改,以刪除原型功能,並使用以下簡單功能:

var http = require('http');
var url = require('url');
var Memcached = require('memcached');
var libAS = require('./libAS');
var cache = new Memcached('localhost:11211');

http.createServer(function(request,response) {
    response.writeHead(200, { 'Content-Type': 'text/plain' , 'Access-Control-Allow-Origin' : 'http://localhost'});
    var url_parts = url.parse(request.url,true);
    var querystring = url_parts.query;
    var channel_id = querystring.channel_id;
    var subscriber = querystring.subscriber;
    var workstamp = querystring.workstamp;

    if(!libAS.exists(querystring.channel_id) || !libAS.exists(querystring.workstamp) || !libAS.exists(querystring.subscriber))
    {
        response.end("Invalid Request");
    }

    fetch(channel_id,cache,function(data){
        if(checkEmpty(data)) endResponse(0,workstamp,response);
        else
        {
            checkSubscriber(channel_id,subscriber,cache,function(valid){
                if(!valid) endResponse(-1,workstamp,response);
                else
                {
                    startLoop(channel_id,workstamp,response,cache);
                }
            });
        }
    });
}).listen(1111,'localhost');

//----------------------------------CHANNEL HANDLING----------------------------------------//

var LoopProp = function(){
    this.count = 0;
    this.limit = 10;
};

var startLoop = function(channel_id,workstamp,response,cache) {
    var current_workstamp = workstamp;
    var prop = new LoopProp();
    checkUpdates(channel_id,current_workstamp,cache,function(updated,new_workstamp){
                if(updated)
                {
                    console.log("Updated. Ending - Old workstamp:"+current_workstamp+" - New workstamp:"+new_workstamp);
                    endResponse(1,new_workstamp,response);
                }
                else
                {
                    current_workstamp = new_workstamp;
                    console.log("Not updated. Workstamp : "+current_workstamp);
                    loop(channel_id,current_workstamp,prop,response,cache);
                }
            });
};

var loop = function(channel_id,workstamp,prop,response,cache) {
    var current_workstamp = workstamp;
    setTimeout(function(){
            checkUpdates(channel_id,current_workstamp,cache,function(updated,new_workstamp){
                if(updated)
                {
                    console.log("Updated. Ending - Old workstamp:"+current_workstamp+" - New workstamp:"+new_workstamp);
                    endResponse(1,new_workstamp,response);
                }
                else
                {
                    current_workstamp = new_workstamp;
                    console.log("Not updated. Workstamp : "+current_workstamp+" - Loop count : "+prop.count);
                    if(prop.count==(prop.limit-1))
                    {
                        endResponse(0,current_workstamp,response);
                    }
                    else
                    {
                        prop.count++;
                        loop(channel_id,current_workstamp,prop,response,cache);
                    }
                }
            });
        },1000);
};

var endResponse = function(code,workstamp,response) {
    response.end(JSON.stringify({'status':code,'workstamp':workstamp}));
};

var checkUpdates = function(channel_id,workstamp,cache,callback) {
    getWorkstamp(channel_id,cache,function(current_workstamp) {
        if(!current_workstamp) callback(false);
        else
        {
            if(workstamp == current_workstamp)
            {
                callback(false,current_workstamp);
            }
            else
            {
                callback(true,current_workstamp);
            }
        }
    });
};

var getWorkstamp = function(channel_id,cache,callback) {
    cache.get(channel_id+':channel'+':workstamp',function(err,data){
        if(err)
        {
            console.log(err);
            callback(false);
        }
        else
        {
            callback(data);
        }
    });
};

var checkSubscriber = function(channel_id,subscriber,cache,callback) {
    cache.get(channel_id+':channel:subscriptions',function(err,data) {
        if(err)
        {
            console.log(err);
            callback(false);
        }
        else
        {
            data = getArray(data);
            for(i=0;i<data.length;i++)
            {
                if(data[i]['id']==subscriber)
                {
                    callback(true);
                    break;
                }
                else
                {
                    if(i == (data.length-1))
                    {
                        callback(false);
                        break;
                    }
                }
            }
        }
    });
};

var fetch = function(channel_id,cache,callback) {
    cache.get(channel_id+':channel',function(err,data){
        if(err)
        {
            console.log(err);
            callback(false);
        }
        else
        {
            callback(data);
        }
    });
};

var checkEmpty = function(obj) {
    if(obj == ':') return true; else return false;
};

var getArray = function(obj) {
    return JSON.parse(obj.toString());
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM