我创建了一个简单的XHR长轮询类,它接受初始化的http请求,然后解析流并在数据片段到达时自动调用函数。
要真正理解我的所作所为,请参阅课程:
function longPollingRequest(http) {
//Define how fragments of data are separated
// onData() is called for every received fragment
this.delimiter = "\n";
//Dummy callback
this.onData = function() {};
//Whether or not to automatically reconnect to the stream source (does not work yet)
this.reconnect = false;
//Self reference for event functions
var _this = this;
//Offset in http.responseText (this one cannot be truncnated until the request is over)
var seeker = 0;
//Whether or not connected
var connected = false;
//Assign events to http request
http.onreadystatechange = readState;
http.onprogress = parseData;
// OVerride HTTPRequest send method for this instance
var oldSend = http.send;
http.send = function() {
connected = true;
oldSend.apply(this, arguments);
}
//Define readystate event
function readState() {
if(this.readyState==2) {
}
if(this.readyState==3||this.readyState==4) {
parseData();
}
if(this.readyState==4) {
if(_this.reconnect==true) //Eventually reconnect
_this.reconnect();
}
}
function parseData(r) {
//Start at the current position in the input, anything before has already been sent to onData()
var seektmp = seeker;
//Loop through the input and seek delimiters
while(seektmp<this.responseText.length) {
if(this.responseText[seektmp]==_this.delimiter) {
//If a delimiter has been found, send the fragment before to onData
_this.onData(this.responseText.substr(seeker+1,seektmp-1-seeker));
//Skip the original seeker to the end of data that has been read (+1 for delimiter)
seeker=seektmp+1; //todo: +delimiter size, instead of just 1
}
//iterate 1 character, until the end of data
seektmp++;
}
}
}
用法:
var http = /**cross browser create request**/;
http.open(...);
var poll = new longPollingRequest(http);
http.send();
现在重点是,我可能不会像这样重新连接http请求:
var http = /**cross browser create request**/;
http.open(...);
http.onload = function() {
this.send(); //ERROR: resource not initialised (requires open() call)
}
http.send();
那么,有没有办法在不知道请求目标的情况下重新连接?