source: TFP-WebServer/WebServer/src/SSE/SseClient.cs@ 490

Last change on this file since 490 was 487, checked in by alloc, 6 months ago

1.1.0.1 Release for V 1.0

File size: 2.9 KB
Line 
1using System;
2using System.IO;
3using System.Net.Sockets;
4using System.Text;
5using SpaceWizards.HttpListener;
6using Webserver.UrlHandlers;
7
8namespace Webserver.SSE {
9 public enum ESseClientWriteResult {
10 Ok,
11 Closed,
12 Error,
13 }
14
15 public class SseClient {
16 private const int keepAliveIntervalSeconds = 10;
17 private static readonly byte[] keepAliveData = Encoding.UTF8.GetBytes (": KeepAlive\n\n");
18
19 private readonly SseHandler parent;
20 private readonly HttpListenerResponse response;
21 private DateTime lastMessageSent = DateTime.Now;
22
23 public SseClient (SseHandler _parent, HttpListenerResponse _response) {
24 parent = _parent;
25 response = _response;
26
27 // Keep the request open
28 _response.SendChunked = true;
29
30 _response.AddHeader ("Content-Type", "text/event-stream");
31 _response.OutputStream.Flush ();
32 }
33
34 public ESseClientWriteResult Write (byte[] _bytes, int _bytesToSend) {
35 HttpListenerResponse resp = response;
36 try {
37 if (!resp.OutputStream.CanWrite) {
38 parent.ClientClosed (this);
39 resp.Close ();
40
41 return ESseClientWriteResult.Closed;
42 }
43
44 resp.OutputStream.Write (_bytes, 0, _bytesToSend);
45 resp.OutputStream.Flush ();
46 lastMessageSent = DateTime.Now;
47 return ESseClientWriteResult.Ok;
48 } catch (IOException e) {
49 parent.ClientClosed (this);
50
51 if (e.InnerException is SocketException se) {
52 if (se.SocketErrorCode == SocketError.ConnectionAborted || se.SocketErrorCode == SocketError.Shutdown) {
53 return ESseClientWriteResult.Closed;
54 }
55
56 Log.Error ($"[Web] [SSE] SocketError ({se.SocketErrorCode.ToStringCached ()}) while trying to write", true);
57 return ESseClientWriteResult.Error;
58 }
59
60 Log.Error ("[Web] [SSE] IOException while trying to write:", true);
61 Log.Exception (e);
62 return ESseClientWriteResult.Error;
63 } catch (Exception e) {
64 parent.ClientClosed (this);
65 resp.Close ();
66
67 Log.Error ("[Web] [SSE] Exception while trying to write:", true);
68 Log.Exception (e);
69
70 return ESseClientWriteResult.Error;
71 }
72 }
73
74 public void HandleKeepAlive () {
75 DateTime now = DateTime.Now;
76 if (!((now - lastMessageSent).TotalSeconds >= keepAliveIntervalSeconds)) {
77 return;
78 }
79
80 Write (keepAliveData, keepAliveData.Length);
81 lastMessageSent = now;
82 }
83
84 }
85}
Note: See TracBrowser for help on using the repository browser.