Winify – Diff between revs 21 and 24

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 21 Rev 24
1 using System; 1 using System;
2 using System.Drawing; 2 using System.Drawing;
3 using System.IO; 3 using System.IO;
4 using System.Net.Http; 4 using System.Net.Http;
5 using System.Net.Http.Headers; 5 using System.Net.Http.Headers;
6 using System.Net.WebSockets; 6 using System.Net.WebSockets;
7 using System.Text; 7 using System.Text;
8 using System.Threading; 8 using System.Threading;
9 using System.Threading.Tasks; 9 using System.Threading.Tasks;
10 using Newtonsoft.Json; 10 using Newtonsoft.Json;
11 using Serilog; 11 using Serilog;
-   12 using Servers;
12 using ClientWebSocket = System.Net.WebSockets.Managed.ClientWebSocket; 13 using ClientWebSocket = System.Net.WebSockets.Managed.ClientWebSocket;
13   14  
14 namespace Winify.Gotify 15 namespace Winify.Gotify
15 { 16 {
16 public class GotifyConnection : IDisposable 17 public class GotifyConnection : IDisposable
17 { 18 {
18 #region Public Events & Delegates 19 #region Public Events & Delegates
19   20  
20 public event EventHandler<GotifyNotificationEventArgs> GotifyNotification; 21 public event EventHandler<GotifyNotificationEventArgs> GotifyNotification;
21   22  
22 #endregion 23 #endregion
23   24  
24 #region Private Delegates, Events, Enums, Properties, Indexers and Fields 25 #region Private Delegates, Events, Enums, Properties, Indexers and Fields
25   26  
26 private CancellationToken _cancellationToken; 27 private CancellationToken _cancellationToken;
27   28  
28 private CancellationTokenSource _cancellationTokenSource; 29 private CancellationTokenSource _cancellationTokenSource;
29   30  
30 private HttpClient _httpClient; 31 private HttpClient _httpClient;
31   32  
32 private Task _runTask; 33 private Task _runTask;
33   34  
34 private ClientWebSocket _webSocketClient; 35 private ClientWebSocket _webSocketClient;
-   36  
-   37 private readonly Server _server;
-   38  
-   39 public GotifyConnection(Server server)
-   40 {
-   41 _server = server;
-   42 }
35   43  
36 #endregion 44 #endregion
37   45  
38 #region Constructors, Destructors and Finalizers 46 #region Constructors, Destructors and Finalizers
39   47  
40 public void Dispose() 48 public void Dispose()
41 { 49 {
42 if (_cancellationTokenSource != null) 50 if (_cancellationTokenSource != null)
43 { 51 {
44 _cancellationTokenSource.Dispose(); 52 _cancellationTokenSource.Dispose();
45 _cancellationTokenSource = null; 53 _cancellationTokenSource = null;
46 } 54 }
47   55  
48 if (_webSocketClient != null) 56 if (_webSocketClient != null)
49 { 57 {
50 _webSocketClient.Dispose(); 58 _webSocketClient.Dispose();
51 _webSocketClient = null; 59 _webSocketClient = null;
52 } 60 }
53   61  
54 if (_httpClient != null) 62 if (_httpClient != null)
55 { 63 {
56 _httpClient.Dispose(); 64 _httpClient.Dispose();
57 _httpClient = null; 65 _httpClient = null;
58 } 66 }
59 } 67 }
60   68  
61 #endregion 69 #endregion
62   70  
63 #region Public Methods 71 #region Public Methods
64   72  
65 public void Start(string username, string password, string url) 73 public void Start(string username, string password, string url)
66 { 74 {
67 if (!Uri.TryCreate(url, UriKind.Absolute, out var httpUri)) 75 if (!Uri.TryCreate(url, UriKind.Absolute, out var httpUri))
68 { 76 {
69 return; 77 return;
70 } 78 }
71   79  
72 // Build the web sockets URI. 80 // Build the web sockets URI.
73 var webSocketsUriBuilder = new UriBuilder(httpUri); 81 var webSocketsUriBuilder = new UriBuilder(httpUri);
74 webSocketsUriBuilder.Scheme = "ws"; 82 webSocketsUriBuilder.Scheme = "ws";
75 webSocketsUriBuilder.Path = $"{webSocketsUriBuilder.Path}/stream"; 83 webSocketsUriBuilder.Path = $"{webSocketsUriBuilder.Path}/stream";
76 var webSocketsUri = webSocketsUriBuilder.Uri; 84 var webSocketsUri = webSocketsUriBuilder.Uri;
77   85  
78 _cancellationTokenSource = new CancellationTokenSource(); 86 _cancellationTokenSource = new CancellationTokenSource();
79 _cancellationToken = _cancellationTokenSource.Token; 87 _cancellationToken = _cancellationTokenSource.Token;
80   88  
81 _httpClient = new HttpClient(); 89 _httpClient = new HttpClient();
82   90  
83 var auth = Convert.ToBase64String(Encoding.Default.GetBytes($"{username}:{password}")); 91 var auth = Convert.ToBase64String(Encoding.Default.GetBytes($"{username}:{password}"));
84   92  
85 _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", auth); 93 _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", auth);
86   94  
87 _runTask = Run(webSocketsUri, httpUri, username, password, _cancellationToken); 95 _runTask = Run(webSocketsUri, httpUri, username, password, _cancellationToken);
88 } 96 }
89   97  
90 public void Stop() 98 public void Stop()
91 { 99 {
92 if (_cancellationTokenSource != null) 100 if (_cancellationTokenSource != null)
93 { 101 {
94 _cancellationTokenSource.Cancel(); 102 _cancellationTokenSource.Cancel();
95 } 103 }
-   104  
-   105 _runTask.Wait(CancellationToken.None);
96 } 106 }
97   107  
98 #endregion 108 #endregion
99   109  
100 #region Private Methods 110 #region Private Methods
101   111  
102 private async Task Run(Uri webSocketsUri, Uri httpUri, string username, string password, 112 private async Task Run(Uri webSocketsUri, Uri httpUri, string username, string password,
103 CancellationToken cancellationToken) 113 CancellationToken cancellationToken)
104 { 114 {
105 try 115 try
106 { 116 {
107 do 117 do
108 { 118 {
109 try 119 try
110 { 120 {
111 using (_webSocketClient = new ClientWebSocket()) 121 using (_webSocketClient = new ClientWebSocket())
112 { 122 {
113 var auth = Convert.ToBase64String(Encoding.Default.GetBytes($"{username}:{password}")); 123 var auth = Convert.ToBase64String(Encoding.Default.GetBytes($"{username}:{password}"));
114   124  
115 _webSocketClient.Options.SetRequestHeader("Authorization", $"Basic {auth}"); 125 _webSocketClient.Options.SetRequestHeader("Authorization", $"Basic {auth}");
116   126  
117 await _webSocketClient.ConnectAsync(webSocketsUri, cancellationToken); 127 await _webSocketClient.ConnectAsync(webSocketsUri, cancellationToken);
118   128  
119 do 129 do
120 { 130 {
121 var payload = new ArraySegment<byte>(new byte[1024]); 131 var payload = new ArraySegment<byte>(new byte[1024]);
122   132  
123 var result = await _webSocketClient.ReceiveAsync(payload, cancellationToken); 133 var result = await _webSocketClient.ReceiveAsync(payload, cancellationToken);
124   134  
125 if (result.Count == 0) 135 if (result.Count == 0)
126 { 136 {
127 continue; 137 continue;
128 } 138 }
129   139  
130 if (payload.Array == null || payload.Count == 0) 140 if (payload.Array == null || payload.Count == 0)
131 { 141 {
132 continue; 142 continue;
133 } 143 }
134   144  
135 var message = Encoding.UTF8.GetString(payload.Array, 0, payload.Count); 145 var message = Encoding.UTF8.GetString(payload.Array, 0, payload.Count);
136   146  
137 var gotifyNotification = JsonConvert.DeserializeObject<GotifyNotification>(message); 147 var gotifyNotification = JsonConvert.DeserializeObject<GotifyNotification>(message);
138 if (gotifyNotification == null) 148 if (gotifyNotification == null)
139 { 149 {
140 continue; 150 continue;
141 } 151 }
-   152  
-   153 gotifyNotification.Server = _server;
142   154  
143 if (!Uri.TryCreate($"{httpUri}/application", UriKind.Absolute, out var applicationUri)) 155 if (!Uri.TryCreate($"{httpUri}/application", UriKind.Absolute, out var applicationUri))
144 { 156 {
145 continue; 157 continue;
146 } 158 }
147   159  
148 var applications = await _httpClient.GetStringAsync(applicationUri); 160 var applications = await _httpClient.GetStringAsync(applicationUri);
149   161  
150 var gotifyApplications = 162 var gotifyApplications =
151 JsonConvert.DeserializeObject<GotifyApplication[]>(applications); 163 JsonConvert.DeserializeObject<GotifyApplication[]>(applications);
152 if (gotifyApplications == null) 164 if (gotifyApplications == null)
153 { 165 {
154 continue; 166 continue;
155 } 167 }
156   168  
157 foreach (var application in gotifyApplications) 169 foreach (var application in gotifyApplications)
158 { 170 {
159 if (application.Id != gotifyNotification.AppId) 171 if (application.Id != gotifyNotification.AppId)
160 { 172 {
161 continue; 173 continue;
162 } 174 }
163   175  
164 if (!Uri.TryCreate($"{httpUri}/{application.Image}", UriKind.Absolute, 176 if (!Uri.TryCreate($"{httpUri}/{application.Image}", UriKind.Absolute,
165 out var applicationImageUri)) 177 out var applicationImageUri))
166 { 178 {
167 continue; 179 continue;
168 } 180 }
169   181  
170 var imageBytes = await _httpClient.GetByteArrayAsync(applicationImageUri); 182 var imageBytes = await _httpClient.GetByteArrayAsync(applicationImageUri);
171   183  
172 if (imageBytes == null || imageBytes.Length == 0) 184 if (imageBytes == null || imageBytes.Length == 0)
173 { 185 {
174 continue; 186 continue;
175 } 187 }
176   188  
177 using (var memoryStream = new MemoryStream(imageBytes)) 189 using (var memoryStream = new MemoryStream(imageBytes))
178 { 190 {
179 var image = Image.FromStream(memoryStream); 191 var image = Image.FromStream(memoryStream);
180   192  
181 GotifyNotification?.Invoke(this, 193 GotifyNotification?.Invoke(this,
182 new GotifyNotificationEventArgs(gotifyNotification, image)); 194 new GotifyNotificationEventArgs(gotifyNotification, image));
183 } 195 }
184   196  
185   197  
186 break; 198 break;
187 } 199 }
188   200  
189 Log.Debug($"Notification message received: {gotifyNotification.Message}"); 201 Log.Debug($"Notification message received: {gotifyNotification.Message}");
190 } while (!cancellationToken.IsCancellationRequested); 202 } while (!cancellationToken.IsCancellationRequested);
191   203  
192 await _webSocketClient.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, 204 await _webSocketClient.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty,
193 CancellationToken.None); 205 CancellationToken.None);
194 } 206 }
195   207  
196 _webSocketClient = null; 208 _webSocketClient = null;
197 } 209 }
198 catch (Exception ex) when (ex is WebSocketException || ex is HttpRequestException) 210 catch (Exception ex) when (ex is WebSocketException || ex is HttpRequestException)
199 { 211 {
200 Log.Warning($"Unable to connect to gotify server: {ex.Message}"); 212 Log.Warning($"Unable to connect to gotify server: {ex.Message}");
201   213  
202 // Reconnect 214 // Reconnect
203 if (_webSocketClient != null) 215 if (_webSocketClient != null)
204 { 216 {
205 _webSocketClient.Abort(); 217 _webSocketClient.Abort();
206 _webSocketClient.Dispose(); 218 _webSocketClient.Dispose();
207 _webSocketClient = null; 219 _webSocketClient = null;
208 } 220 }
209   221  
210 await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); 222 await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
211 } 223 }
212 } while (!cancellationToken.IsCancellationRequested); 224 } while (!cancellationToken.IsCancellationRequested);
213 } 225 }
214 catch (Exception ex) when (ex is OperationCanceledException || ex is ObjectDisposedException) 226 catch (Exception ex) when (ex is OperationCanceledException || ex is ObjectDisposedException)
215 { 227 {
216 } 228 }
217 catch (Exception ex) 229 catch (Exception ex)
218 { 230 {
219 Log.Warning(ex, "Failure running connection loop."); 231 Log.Warning(ex, "Failure running connection loop.");
220 } 232 }
221 } 233 }
222   234  
223 #endregion 235 #endregion
224 } 236 }
225 } 237 }
226   238  
227
Generated by GNU Enscript 1.6.5.90.
239
Generated by GNU Enscript 1.6.5.90.
228   240  
229   241  
230   242