Index: /binary-improvements2/WebServer/src/SSE/AbsEvent.cs
===================================================================
--- /binary-improvements2/WebServer/src/SSE/AbsEvent.cs	(revision 408)
+++ /binary-improvements2/WebServer/src/SSE/AbsEvent.cs	(revision 409)
@@ -9,11 +9,14 @@
 namespace Webserver.SSE {
 	public abstract class AbsEvent {
-		private const int EncodingBufferSize = 1024 * 1024;
+		private const int encodingBufferSize = 1024 * 1024;
+		private const int keepAliveIntervalSeconds = 10;
+		private static readonly byte[] keepAliveData = Encoding.UTF8.GetBytes (": KeepAlive\n\n");
 
-		private readonly SseHandler Parent;
+		private readonly SseHandler parent;
 		public readonly string Name;
 
 		private readonly byte[] encodingBuffer;
 		private readonly StringBuilder stringBuilder = new StringBuilder ();
+		private DateTime lastMessageSent;
 
 		private readonly List<HttpListenerResponse> openStreams = new List<HttpListenerResponse> ();
@@ -28,7 +31,7 @@
 		protected AbsEvent (SseHandler _parent, bool _reuseEncodingBuffer = true, string _name = null) {
 			Name = _name ?? GetType ().Name;
-			Parent = _parent;
+			parent = _parent;
 			if (_reuseEncodingBuffer) {
-				encodingBuffer = new byte[EncodingBufferSize];
+				encodingBuffer = new byte[encodingBufferSize];
 			}
 		}
@@ -43,8 +46,10 @@
 		protected void SendData (string _eventName, string _data) {
 			sendQueue.Enqueue ((_eventName, _data));
-			Parent.SignalSendQueue ();
+			parent.SignalSendQueue ();
 		}
 
 		public void ProcessSendQueue () {
+			bool dataSent = false;
+			
 			while (sendQueue.HasData ()) {
 				(string eventName, string data) = sendQueue.Dequeue ();
@@ -76,41 +81,55 @@
 				}
 
-				for (int i = openStreams.Count - 1; i >= 0; i--) {
-					HttpListenerResponse resp = openStreams [i];
-					try {
-						if (resp.OutputStream.CanWrite) {
-							resp.OutputStream.Write (buf, 0, bytesToSend);
-							resp.OutputStream.Flush ();
-						} else {
-							currentlyOpen--;
-							totalClosed++;
+				dataSent = true;
 
-							logError ("Can not write to endpoint, closing", true);
-							openStreams.RemoveAt (i);
-							resp.Close ();
-						}
-					} catch (IOException e) {
+				sendBufToListeners (buf, bytesToSend);
+			}
+
+			DateTime now = DateTime.Now;
+			if (dataSent) {
+				lastMessageSent = now;
+			} else if ((now - lastMessageSent).TotalSeconds >= keepAliveIntervalSeconds) {
+				sendBufToListeners (keepAliveData, keepAliveData.Length);
+				lastMessageSent = now;
+			}
+		}
+
+		private void sendBufToListeners (byte[] _bytes, int _bytesToSend) {
+			for (int i = openStreams.Count - 1; i >= 0; i--) {
+				HttpListenerResponse resp = openStreams [i];
+				try {
+					if (resp.OutputStream.CanWrite) {
+						resp.OutputStream.Write (_bytes, 0, _bytesToSend);
+						resp.OutputStream.Flush ();
+					} else {
 						currentlyOpen--;
 						totalClosed++;
 
+						logError ("Can not write to endpoint, closing", true);
 						openStreams.RemoveAt (i);
-
-						if (e.InnerException is SocketException se) {
-							if (se.SocketErrorCode != SocketError.ConnectionAborted && se.SocketErrorCode != SocketError.Shutdown) {
-								logError ($"SocketError ({se.SocketErrorCode.ToStringCached ()}) while trying to write", true);
-							}
-						} else {
-							logError ("IOException while trying to write:", true);
-							Log.Exception (e);
-						}
-					} catch (Exception e) {
-						currentlyOpen--;
-						totalClosed++;
-
-						openStreams.RemoveAt (i);
-						logError ("Exception while trying to write:", true);
-						Log.Exception (e);
 						resp.Close ();
 					}
+				} catch (IOException e) {
+					currentlyOpen--;
+					totalClosed++;
+
+					openStreams.RemoveAt (i);
+
+					if (e.InnerException is SocketException se) {
+						if (se.SocketErrorCode != SocketError.ConnectionAborted && se.SocketErrorCode != SocketError.Shutdown) {
+							logError ($"SocketError ({se.SocketErrorCode.ToStringCached ()}) while trying to write", true);
+						}
+					} else {
+						logError ("IOException while trying to write:", true);
+						Log.Exception (e);
+					}
+				} catch (Exception e) {
+					currentlyOpen--;
+					totalClosed++;
+
+					openStreams.RemoveAt (i);
+					logError ("Exception while trying to write:", true);
+					Log.Exception (e);
+					resp.Close ();
 				}
 			}
@@ -123,7 +142,5 @@
 		}
 
-		public virtual int DefaultPermissionLevel () {
-			return 0;
-		}
+		public virtual int DefaultPermissionLevel () => 0;
 	}
 }
