Skip to content

Commit 74dfeb6

Browse files
authored
Merge pull request #9 from byjg/jquery-sse-8
jquery-sse-8 Fix behavior on Edge/IE
2 parents 8d95ced + f6b5d07 commit 74dfeb6

File tree

1 file changed

+108
-69
lines changed

1 file changed

+108
-69
lines changed

jquery.sse.js

Lines changed: 108 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
$.extend(settings, customSettings);
3030

3131
sse._url = url;
32+
sse._remoteHost = null;
3233
sse._settings = settings;
3334

3435
// Start the proper EventSource object or Ajax fallback
@@ -64,7 +65,6 @@
6465
this.type = null;
6566

6667
return true;
67-
6868
};
6969

7070
return sse;
@@ -102,92 +102,131 @@
102102
me.instance = {successCount: 0, id: null, retry: 3000, data: "", event: ""};
103103
runAjax(me);
104104
}
105+
106+
function handleAjax(me, receivedData) {
107+
if (!me.instance) {
108+
return;
109+
}
110+
111+
if (me.instance.successCount++ === 0) {
112+
me._settings.onOpen();
113+
}
114+
115+
var lines = receivedData.split("\n");
116+
117+
// Process the return to generate a compatible SSE response
118+
me.instance.data = "";
119+
var countBreakLine = 0;
120+
for (var key in lines) {
121+
var separatorPos = lines[key].indexOf(":");
122+
var item = [
123+
lines[key].substr(0, separatorPos),
124+
lines[key].substr(separatorPos + 1)
125+
];
126+
switch (item[0]) {
127+
// If the first part is empty, needed to check another sequence
128+
case "":
129+
if (!item[1] && countBreakLine++ === 1) { // Avoid comments!
130+
eventMessage = {
131+
data: me.instance.data,
132+
lastEventId: me.instance.id,
133+
origin: 'http://' + me._remoteHost,
134+
returnValue: true
135+
};
136+
137+
// If there are a custom event then call it
138+
if (me.instance.event && me._settings.events[me.instance.event]) {
139+
me._settings.events[me.instance.event](eventMessage);
140+
} else {
141+
me._settings.onMessage(eventMessage);
142+
}
143+
me.instance.data = "";
144+
me.instance.event = "";
145+
countBreakLine = 0;
146+
}
147+
break;
148+
149+
// Define the new retry object;
150+
case "retry":
151+
countBreakLine = 0;
152+
me.instance.retry = parseInt(item[1].trim());
153+
break;
154+
155+
// Define the new ID
156+
case "id":
157+
countBreakLine = 0;
158+
me.instance.id = item[1].trim();
159+
break;
160+
161+
// Define a custom event
162+
case "event":
163+
countBreakLine = 0;
164+
me.instance.event = item[1].trim();
165+
break;
166+
167+
// Define the data to be processed.
168+
case "data":
169+
countBreakLine = 0;
170+
me.instance.data += (me.instance.data !== "" ? "\n" : "") + item[1].trim();
171+
break;
172+
173+
default:
174+
countBreakLine = 0;
175+
}
176+
}
177+
}
178+
179+
function getRemoteHost(me) {
180+
$.ajax({
181+
type: 'HEAD',
182+
headers: me._settings.headers,
183+
url: me._url,
184+
complete: function(xhr) {
185+
me._remoteHost = xhr.getResponseHeader('Host');
186+
}
187+
});
188+
}
105189

106190
// Handle the continous Ajax request (fallback)
107191
function runAjax(me) {
108192
if (!me.instance) {
109193
return;
110194
}
111195

196+
if (!me._remoteHost) {
197+
getRemoteHost(me);
198+
}
199+
112200
var headers = {'Last-Event-ID': me.instance.id};
113201

114202
$.extend(headers, me._settings.headers);
115203

204+
// https://stackoverflow.com/questions/7740646/jquery-read-ajax-stream-incrementally
205+
var lastResponseLen = false;
206+
var thisResponse = "";
116207
$.ajax({
117208
url: me._url,
118209
method: 'GET',
119210
headers: headers,
120-
success: function (receivedData, status, info) {
121-
if (!me.instance) {
122-
return;
123-
}
124-
125-
if (me.instance.successCount++ === 0) {
126-
me._settings.onOpen();
127-
}
211+
xhrFields: {
212+
onprogress: function(e) {
213+
var response = e.currentTarget.response;
214+
if(lastResponseLen === false) {
215+
thisResponse += response;
216+
} else {
217+
thisResponse += response.substring(lastResponseLen);
218+
}
219+
lastResponseLen = response.length;
128220

129-
var lines = receivedData.split("\n");
130-
131-
// Process the return to generate a compatible SSE response
132-
me.instance.data = "";
133-
var countBreakLine = 0;
134-
for (var key in lines) {
135-
var separatorPos = lines[key].indexOf(":");
136-
var item = [
137-
lines[key].substr(0, separatorPos),
138-
lines[key].substr(separatorPos + 1)
139-
];
140-
switch (item[0]) {
141-
// If the first part is empty, needed to check another sequence
142-
case "":
143-
if (!item[1] && countBreakLine++ === 1) { // Avoid comments!
144-
eventMessage = {
145-
data: me.instance.data,
146-
lastEventId: me.instance.id,
147-
origin: 'http://' + info.getResponseHeader('Host'),
148-
returnValue: true
149-
};
150-
151-
// If there are a custom event then call it
152-
if (me.instance.event && me._settings.events[me.instance.event]) {
153-
me._settings.events[me.instance.event](eventMessage);
154-
} else {
155-
me._settings.onMessage(eventMessage);
156-
}
157-
me.instance.data = "";
158-
me.instance.event = "";
159-
countBreakLine = 0;
160-
}
161-
break;
162-
163-
// Define the new retry object;
164-
case "retry":
165-
countBreakLine = 0;
166-
me.instance.retry = parseInt(item[1].trim());
167-
break;
168-
169-
// Define the new ID
170-
case "id":
171-
countBreakLine = 0;
172-
me.instance.id = item[1].trim();
173-
break;
174-
175-
// Define a custom event
176-
case "event":
177-
countBreakLine = 0;
178-
me.instance.event = item[1].trim();
179-
break;
180-
181-
// Define the data to be processed.
182-
case "data":
183-
countBreakLine = 0;
184-
me.instance.data += (me.instance.data !== "" ? "\n" : "") + item[1].trim();
185-
break;
186-
187-
default:
188-
countBreakLine = 0;
221+
var hasFullMessage = thisResponse.lastIndexOf("\n\n");
222+
if (hasFullMessage >= 0) {
223+
var chunk = thisResponse.substring(0, hasFullMessage + 2);
224+
thisResponse = thisResponse.substring(hasFullMessage + 2);
225+
handleAjax(me, chunk)
189226
}
190227
}
228+
},
229+
success: function () {
191230
setTimeout(function () {
192231
runAjax(me);
193232
}, me.instance.retry);

0 commit comments

Comments
 (0)