Server-Sent Events (EventSource) [full code]
Posted: Fri Apr 21, 2017 10:15 am
Server-Sent Events (previously known as EventSource) is an extremely useful thing for webmasters. There doesn't seem to be any mention of SSE on this forum, so I'm posting my code here in case anyone wants a quick start to using SSE in the future. This code works in my set-up, using Xampp (Apache) in offline testing with Chrome.
Here's the JavaScript:
The function OpenSSELink() should be called once, after the webpage has been loaded.
Now for the server side. Compile this as a console program called "sse.exe":
I hope this is useful to somebody. Be aware that you might need to configure your server to allow SSE connections.
Here's the JavaScript:
Code: Select all
var sse_object = null;
var unique_client_id = "ucid"+(Math.random()*10000); // this is for coordinating communication between the server and this client. you might find it necessary if using both SSE and AJAX
function OpenSSELink() {
sse_object = new EventSource("sse.exe?&clientid="+unique_client_id);
sse_object.onerror = function(e) { alert("EventSource failed.\n"+e.error); };
sse_object.onmessage = ReceiveSSE;
}
function ReceiveSSE(e) {
if (e.data=="DUMMY") {
console.log("DUMMY SSE");
// do nothing with dummy messages
} else {
console.log("REAL SSE");
// assuming that the sse.exe is sending JavaScript that just needs to be run, eval() it:
eval(e.data);
}
}
function CloseSSELink() {
if (sse_object) {sse_object.close(); }
}
Now for the server side. Compile this as a console program called "sse.exe":
Code: Select all
clientid.s = GetURLPart("http://www.test.com?"+GetEnvironmentVariable("QUERY_STRING"),"clientid")
If clientid = ""
; this is an arbitrary thing, a way to uniquely identify the client to your server. you might find it necessary if using both AJAX and SSE to communicate with the client
End
EndIf
Macro SendData(unqdta)
HttpAnswer.s = "Content-type: text/event-stream" +#CRLF$+#CRLF$+ "data: "+unqdta +#CRLF$+#CRLF$
length = StringByteLength(HttpAnswer,#PB_UTF8) ; UTF8 encoding is mandatory for server-sent events
*buffer = AllocateMemory(length)
PokeS(*buffer,HttpAnswer,length,#PB_UTF8)
WriteConsoleData(*buffer,MemoryStringLength(*buffer,#PB_UTF8|#PB_ByteLength))
lastsentsomething = Date()
EndMacro
OpenConsole()
lastsentsomething.i = Date()
Repeat
; your code
; your code
;If your code
; SendData("your code") // in this set-up, the data sent should be JavaScript code - try "alert('Hello from PB! "+Str(Random(9999))+"')"
;EndIf
; your code
; your code
; below is mandatory for keeping the connection alive
; if nothing sent to client for 27 seconds, send a dummy message (tell your JavaScript to ignore these messages)
If (Date()-lastsentsomething)>27
SendData("DUMMY")
EndIf
Delay(500) ; change this to whatever you want
ForEver
CloseConsole()