/trunk/Winify/Gotify/GotifyConnection.cs |
@@ -24,17 +24,17 @@ |
|
#region Private Delegates, Events, Enums, Properties, Indexers and Fields |
|
private readonly Server _server; |
|
private CancellationToken _cancellationToken; |
|
private CancellationTokenSource _cancellationTokenSource; |
|
private HttpClient _httpClient; |
|
private Task _runTask; |
|
private ClientWebSocket _webSocketClient; |
#endregion |
|
private readonly Server _server; |
#region Constructors, Destructors and Finalizers |
|
public GotifyConnection(Server server) |
{ |
@@ -41,10 +41,6 @@ |
_server = server; |
} |
|
#endregion |
|
#region Constructors, Destructors and Finalizers |
|
public void Dispose() |
{ |
if (_cancellationTokenSource != null) |
@@ -52,27 +48,15 @@ |
_cancellationTokenSource.Dispose(); |
_cancellationTokenSource = null; |
} |
|
if (_webSocketClient != null) |
{ |
_webSocketClient.Dispose(); |
_webSocketClient = null; |
} |
|
if (_httpClient != null) |
{ |
_httpClient.Dispose(); |
_httpClient = null; |
} |
} |
|
#endregion |
|
#region Public Methods |
|
public void Start(string username, string password, string url) |
public void Start() |
{ |
if (!Uri.TryCreate(url, UriKind.Absolute, out var httpUri)) |
if (!Uri.TryCreate(_server.Url, UriKind.Absolute, out var httpUri)) |
{ |
return; |
} |
@@ -86,13 +70,7 @@ |
_cancellationTokenSource = new CancellationTokenSource(); |
_cancellationToken = _cancellationTokenSource.Token; |
|
_httpClient = new HttpClient(); |
|
var auth = Convert.ToBase64String(Encoding.Default.GetBytes($"{username}:{password}")); |
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", auth); |
|
_runTask = Run(webSocketsUri, httpUri, username, password, _cancellationToken); |
_runTask = Run(webSocketsUri, httpUri, _server.Username, _server.Password, _cancellationToken); |
} |
|
public void Stop() |
@@ -101,8 +79,6 @@ |
{ |
_cancellationTokenSource.Cancel(); |
} |
|
_runTask.Wait(CancellationToken.None); |
} |
|
#endregion |
@@ -118,19 +94,19 @@ |
{ |
try |
{ |
using (_webSocketClient = new ClientWebSocket()) |
using (var webSocketClient = new ClientWebSocket()) |
{ |
var auth = Convert.ToBase64String(Encoding.Default.GetBytes($"{username}:{password}")); |
|
_webSocketClient.Options.SetRequestHeader("Authorization", $"Basic {auth}"); |
webSocketClient.Options.SetRequestHeader("Authorization", $"Basic {auth}"); |
|
await _webSocketClient.ConnectAsync(webSocketsUri, cancellationToken); |
await webSocketClient.ConnectAsync(webSocketsUri, cancellationToken); |
|
do |
{ |
var payload = new ArraySegment<byte>(new byte[1024]); |
|
var result = await _webSocketClient.ReceiveAsync(payload, cancellationToken); |
var result = await webSocketClient.ReceiveAsync(payload, cancellationToken); |
|
if (result.Count == 0) |
{ |
@@ -144,31 +120,76 @@ |
|
var message = Encoding.UTF8.GetString(payload.Array, 0, payload.Count); |
|
var gotifyNotification = JsonConvert.DeserializeObject<GotifyNotification>(message); |
if (gotifyNotification == null) |
if (!(JsonConvert.DeserializeObject<GotifyNotification>(message) is GotifyNotification |
gotifyNotification)) |
{ |
Log.Warning($"Could not deserialize gotify notification: {message}"); |
|
continue; |
} |
|
gotifyNotification.Server = _server; |
|
if (!Uri.TryCreate($"{httpUri}/application", UriKind.Absolute, out var applicationUri)) |
if (!Uri.TryCreate($"{httpUri}/application", UriKind.Absolute, |
out var applicationUri)) |
{ |
continue; |
} |
|
var applications = await _httpClient.GetStringAsync(applicationUri); |
var image = await RetrieveGotifyApplicationImage(gotifyNotification.AppId, httpUri, |
applicationUri, auth, cancellationToken); |
|
GotifyNotification?.Invoke(this, |
new GotifyNotificationEventArgs(gotifyNotification, image)); |
|
Log.Debug($"Notification message received: {gotifyNotification.Message}"); |
} while (!cancellationToken.IsCancellationRequested); |
} |
} |
catch (Exception ex) when (ex is WebSocketException || ex is HttpRequestException) |
{ |
// Reconnect |
Log.Warning($"Unable to connect to gotify server: {ex.Message}"); |
|
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); |
} |
} while (!cancellationToken.IsCancellationRequested); |
} |
catch (Exception ex) when (ex is OperationCanceledException || ex is ObjectDisposedException) |
{ |
} |
catch (Exception ex) |
{ |
Log.Warning(ex, "Failure running connection loop."); |
} |
|
var e = "o"; |
} |
|
private static async Task<Image> RetrieveGotifyApplicationImage(int appId, Uri httpUri, Uri applicationUri, |
string auth, |
CancellationToken cancellationToken) |
{ |
using (var httpClient = new HttpClient()) |
{ |
httpClient.DefaultRequestHeaders.Authorization = |
new AuthenticationHeaderValue("Basic", auth); |
|
var applicationResponse = await httpClient.GetAsync(applicationUri, cancellationToken); |
|
var applications = await applicationResponse.Content.ReadAsStringAsync(); |
|
var gotifyApplications = |
JsonConvert.DeserializeObject<GotifyApplication[]>(applications); |
|
if (gotifyApplications == null) |
{ |
continue; |
return null; |
} |
|
foreach (var application in gotifyApplications) |
{ |
if (application.Id != gotifyNotification.AppId) |
if (application.Id != appId) |
{ |
continue; |
} |
@@ -179,59 +200,20 @@ |
continue; |
} |
|
var imageBytes = await _httpClient.GetByteArrayAsync(applicationImageUri); |
var imageResponse = await httpClient.GetAsync(applicationImageUri, cancellationToken); |
|
if (imageBytes == null || imageBytes.Length == 0) |
using (var memoryStream = new MemoryStream()) |
{ |
continue; |
} |
await imageResponse.Content.CopyToAsync(memoryStream); |
|
using (var memoryStream = new MemoryStream(imageBytes)) |
{ |
var image = Image.FromStream(memoryStream); |
|
GotifyNotification?.Invoke(this, |
new GotifyNotificationEventArgs(gotifyNotification, image)); |
return Image.FromStream(memoryStream); |
} |
|
|
break; |
} |
|
Log.Debug($"Notification message received: {gotifyNotification.Message}"); |
} while (!cancellationToken.IsCancellationRequested); |
|
await _webSocketClient.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, |
CancellationToken.None); |
} |
|
_webSocketClient = null; |
return null; |
} |
catch (Exception ex) when (ex is WebSocketException || ex is HttpRequestException) |
{ |
Log.Warning($"Unable to connect to gotify server: {ex.Message}"); |
|
// Reconnect |
if (_webSocketClient != null) |
{ |
_webSocketClient.Abort(); |
_webSocketClient.Dispose(); |
_webSocketClient = null; |
} |
|
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); |
} |
} while (!cancellationToken.IsCancellationRequested); |
} |
catch (Exception ex) when (ex is OperationCanceledException || ex is ObjectDisposedException) |
{ |
} |
catch (Exception ex) |
{ |
Log.Warning(ex, "Failure running connection loop."); |
} |
} |
|
#endregion |
} |
} |