【问题标题】:node.js Implementing http server - creating res req - browser stucks after first loadingnode.js实现http服务器-创建res req-第一次加载后浏览器卡住
【发布时间】:2014-01-17 16:27:42
【问题描述】:

我想与您分享我设计自己的 http 服务器的方式,看看是否有我没有注意到的问题。 首先,我将我的 http 模块与 express 服务器一起使用。 我的服务器目前正在“工作”。但。我能够加载一个页面。但是当我尝试刷新时(在第一页加载之后),看起来有待处理的请求并且浏览器卡在加载中。

我正在做以下事情:

  1. 解析数据直到我有\r\n\r\n,切割数据,以便我从第一部分(在\r\n\r\n 之前)创建一个请求对象,并保留第二部分(在\r\n\r\n之后),因为客户端可能会一个接一个地立即发送请求。
  2. 每次我完成请求对象的创建,我都会调用服务器的处理程序,并将我创建的请求对象 + 新的响应对象(我也创建)提供给它。

我的问题是:

  1. 这是一个好的设计吗?
  2. 在我上面的方法中,如果我要一个接一个地请求,我将使用两个新请求和两个新响应对服务器处理程序进行两次调用。我如何确保每个响应都不会被另一个响应打断? (他们正在写入同一个套接字)。或者快递服务器应该处理它?

这是我的模块:

var net = require('net');
var incomingMessage=require('./IncomingMessage');
var server;


var util = require('util');


var miniHttp;
miniHttp = {

STATUS_CODES: {
    404: 'Not Found',
    200: 'OK',
    204: 'No Content',
    205: 'Method Not Allowed',
    500: 'Internal Server Error'
},
Server: require('events').EventEmitter,


createServer: function (handler) {
    console.log('Server Started');
    var Server = require('events').EventEmitter;

    server = net.createServer(function (socket) {
        console.log('\n');
        console.log('*****************');
        console.log('SERVER: got a connection');
        /**
         *   Checking if timout or fallback timeout was set, if it wasn't defines the defaults (2 minutes).
         */
        if(server.timeout==null){
             console.log('server.timeout is null');
            server.timeout=120000;

            if(server.timeoutCallBack==null){
                server.timeoutCallBack=function(){console.log('about to destroy the function because of 2 min timeout');socket.destroy();};
            }
        }

        //Sets the timeout for every socket.
        socket.setTimeout(server.timeout,server.timeoutCallBack);

        var self = this;
        var IncomingMessage = require('./IncomingMessage');
        var ServerResponse = require('./ServerResponse');
        var req = '';
        var res;
        var socketData = {rawRequest: '', bodyLengthSent: 0};
        socket.on("data", function (data) {
            console.log('SOCKET: Received new data');
            console.log('SOCKET: data is ' + data);

            //For every new chunk of data, checks if there is a pending request which its body wasn't sent.
            if (req.method == "POST" && !req.isBodySent) {
                console.log('should send body');
                sendBody(socketData, data, req);
            }

            else{
                //Parsing the request by calling parseRequest function, very time there is enough data for a request
                //, Creating new request, when new request is ready, a request event is emitted
                parseRequest(socket, data, function (finalizedRequest) {
                    res = new ServerResponse(socket);
                    req = finalizedRequest;
                    self.emit('request', socketData,req, res,sendBody);
                });
            }


        });
        //timeout on the socket causes the server to emit a timeout
        socket.on('timeout',function(){self.emit('timeout',socket);});
        //error on the socket causes the server to emit an error
        socket.on("error",function(){self.emit('clientError',socket);});


        //Message parser,
        var rawRequestToSend = '';
        var endOfHttpMessageRegexp = /\r\n\r\n/g;
        var isContainsEndOfMessage;
        function parseRequest(socket, data, callBackFunction) {
            //First, adding the new data to the data that was already collected
            socketData.rawRequest += data;
            isContainsEndOfMessage = endOfHttpMessageRegexp.exec(socketData.rawRequest);
            //Checking if now, after the new data, there is a sign of end of message: \r\n\r\n
            if (isContainsEndOfMessage) {
                //if contains end of message , taking the first part till the \r\n\r\n and creating with it a new
                //request. the second part is kept
                rawRequestToSend = socketData.rawRequest.substring(0, socketData.rawRequest.indexOf('\r\n\r\n'));
                socketData.rawRequest = socketData.rawRequest.substring(socketData.rawRequest.indexOf('\r\n\r\n') + 4, socketData.rawRequest.length);
                console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
                console.log('rawRequest left is: '+socketData.rawRequest+'######');
                console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
                callBackFunction(new IncomingMessage(socket, rawRequestToSend));
            }

        }

        /**
         *  getting the body if its a POST request,then passes the data through event 'data' on req object
         * @param socketData
         * @param data
         * @param req
         */
        function sendBody(socketData, data, req) {
            if (req.method == "POST") {
                console.log('Send Body Function');
                var contentLength = req.headers['content-length'];
                socketData.rawRequest += data;
                //Checks if we the body is shorter then what should be sent, if its, we're sending all the data,
                //And emptying the queue (rawRequest)
                if ((socketData.bodyLengthSent + socketData.rawRequest.length) < contentLength) {
                    req.emit('data', socketData.rawRequest);
                    socketData.bodyLengthSent += socketData.rawRequest.length;
                    socketData.rawRequest = '';
                }

                //If the data sent is bigger from the body, we send only the relevant data
                if ((socketData.bodyLengthSent + socketData.rawRequest.length) >= contentLength) {
                    req.emit('data', socketData.rawRequest.substring(0, (contentLength - socketData.bodyLengthSent)));
                    socketData.rawRequest = socketData.rawRequest.substring((contentLength - socketData.bodyLengthSent), socketData.rawRequest.length);
                    req.emit('end');
                    req.isBodySent = true;
                    socketData.bodyLengthSent = 0;
                }
            }
        }


    });

    server.on('request', function (socketData,req, res,sendBody) {
        handler(req, res);
        sendBody(socketData,req,res);

    });

    util.inherits(server, Server);
    server.prototype.setTimeout=function(msecs,callback){
            server.timeout=msecs;
            server.timeoutCallBack=callback;
     };

    return server;

}


};



 module.exports=miniHttp;

【问题讨论】:

  • 请提供SSCCE(有效且语法正确的代码),以便我们重现您的问题。
  • @remus 谢谢,我马上补充。

标签: node.js sockets http express


【解决方案1】:

好的。问题是我在函数之外定义了正则表达式:

var endOfHttpMessageRegexp= /\r\n\r\n/g;
function parseRequest(socket, data, callBackFunction) {

所以它以某种方式保留了最后一场比赛的信息(我不明白它是如何工作的)。

而不是把它放在里面:

var endOfHttpMessageRegexp;
function parseRequest(socket, data, callBackFunction) {
     endOfHttpMessageRegexp = /\r\n\r\n/g;

【讨论】:

    猜你喜欢
    • 2020-11-20
    • 1970-01-01
    • 2014-09-22
    • 1970-01-01
    • 1970-01-01
    • 2017-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多