【发布时间】:2014-01-17 16:27:42
【问题描述】:
我想与您分享我设计自己的 http 服务器的方式,看看是否有我没有注意到的问题。 首先,我将我的 http 模块与 express 服务器一起使用。 我的服务器目前正在“工作”。但。我能够加载一个页面。但是当我尝试刷新时(在第一页加载之后),看起来有待处理的请求并且浏览器卡在加载中。
我正在做以下事情:
- 解析数据直到我有\r\n\r\n,切割数据,以便我从第一部分(在\r\n\r\n 之前)创建一个请求对象,并保留第二部分(在\r\n\r\n之后),因为客户端可能会一个接一个地立即发送请求。
- 每次我完成请求对象的创建,我都会调用服务器的处理程序,并将我创建的请求对象 + 新的响应对象(我也创建)提供给它。
我的问题是:
- 这是一个好的设计吗?
- 在我上面的方法中,如果我要一个接一个地请求,我将使用两个新请求和两个新响应对服务器处理程序进行两次调用。我如何确保每个响应都不会被另一个响应打断? (他们正在写入同一个套接字)。或者快递服务器应该处理它?
这是我的模块:
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