Winify

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 24  →  ?path2? @ 25
/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,18 +48,6 @@
_cancellationTokenSource.Dispose();
_cancellationTokenSource = null;
}
 
if (_webSocketClient != null)
{
_webSocketClient.Dispose();
_webSocketClient = null;
}
 
if (_httpClient != null)
{
_httpClient.Dispose();
_httpClient = null;
}
}
 
#endregion
@@ -70,9 +54,9 @@
 
#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,81 +120,37 @@
 
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);
 
var gotifyApplications =
JsonConvert.DeserializeObject<GotifyApplication[]>(applications);
if (gotifyApplications == null)
{
continue;
}
GotifyNotification?.Invoke(this,
new GotifyNotificationEventArgs(gotifyNotification, image));
 
foreach (var application in gotifyApplications)
{
if (application.Id != gotifyNotification.AppId)
{
continue;
}
 
if (!Uri.TryCreate($"{httpUri}/{application.Image}", UriKind.Absolute,
out var applicationImageUri))
{
continue;
}
 
var imageBytes = await _httpClient.GetByteArrayAsync(applicationImageUri);
 
if (imageBytes == null || imageBytes.Length == 0)
{
continue;
}
 
using (var memoryStream = new MemoryStream(imageBytes))
{
var image = Image.FromStream(memoryStream);
 
GotifyNotification?.Invoke(this,
new GotifyNotificationEventArgs(gotifyNotification, image));
}
 
 
break;
}
 
Log.Debug($"Notification message received: {gotifyNotification.Message}");
} while (!cancellationToken.IsCancellationRequested);
 
await _webSocketClient.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty,
CancellationToken.None);
}
 
_webSocketClient = null;
}
catch (Exception ex) when (ex is WebSocketException || ex is HttpRequestException)
{
// Reconnect
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);
@@ -230,8 +162,58 @@
{
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)
{
return null;
}
 
foreach (var application in gotifyApplications)
{
if (application.Id != appId)
{
continue;
}
 
if (!Uri.TryCreate($"{httpUri}/{application.Image}", UriKind.Absolute,
out var applicationImageUri))
{
continue;
}
 
var imageResponse = await httpClient.GetAsync(applicationImageUri, cancellationToken);
 
using (var memoryStream = new MemoryStream())
{
await imageResponse.Content.CopyToAsync(memoryStream);
 
return Image.FromStream(memoryStream);
}
}
}
 
return null;
}
 
#endregion
}
}