Winify – Diff between revs 12 and 18

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