Server-Sent Events (EventSource) [full code]

Share your advanced PureBasic knowledge/code with the community.
Seymour Clufley
Addict
Addict
Posts: 1233
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Server-Sent Events (EventSource) [full code]

Post by Seymour Clufley »

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:

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(); }
}
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":

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()
I hope this is useful to somebody. Be aware that you might need to configure your server to allow SSE connections.
Last edited by Seymour Clufley on Sun Apr 23, 2017 3:21 pm, edited 3 times in total.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Server-Sent events (EventSource) [full code]

Post by IdeasVacuum »

Great value, thanks for sharing your code Seymour.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
Seymour Clufley
Addict
Addict
Posts: 1233
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Re: Server-Sent Events (EventSource) [full code]

Post by Seymour Clufley »

Thanks, IV. The code is not complicated, but there were a few things I did wrong when I first attempted this (ie. not using UTF8, not keeping the connection alive, etc.) and these could trip up other people who want to use SSE. And besides that, I tend to think that, if people have a quickstart example right in front of them, they are more likely to give something a try in the first place. In the case of SSE, it is a truly invaluable technology, so I hope at least one person tries out this code and decides to use SSE on their own website. :)
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
Seymour Clufley
Addict
Addict
Posts: 1233
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Re: Server-Sent Events (EventSource) [full code]

Post by Seymour Clufley »

EDIT: fixed a few errors in the code.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
QuimV
Enthusiast
Enthusiast
Posts: 337
Joined: Mon May 29, 2006 11:29 am
Location: BARCELONA - SPAIN

Re: Server-Sent Events (EventSource) [full code]

Post by QuimV »

:cry:
I can not get it to work.

In Chrome browser, I get an alert message: "EventSource failed"
I get too a Console error: "EventSource cannot load file:///C:/Users/QuimV/Desktop/ServerSentEvents/sse.exe?&clientid=ucid5153.326722547473. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https."

Could you describe how to proceed correctly to take a test?

Thanks in advanced.
QuimV
Seymour Clufley
Addict
Addict
Posts: 1233
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Re: Server-Sent Events (EventSource) [full code]

Post by Seymour Clufley »

You need to set up a local offline server, using something like Xampp.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
QuimV
Enthusiast
Enthusiast
Posts: 337
Joined: Mon May 29, 2006 11:29 am
Location: BARCELONA - SPAIN

Re: Server-Sent Events (EventSource) [full code]

Post by QuimV »

OK @Seymour
Thanks a lot
QuimV
Post Reply