Winify – Diff between revs 3 and 12

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