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

Last change on this file since 499 was 499, checked in by alloc, 4 months ago

*Fixed: Chat code
*Fixed: SSE connection counting, added connection set up logging

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