diff --git a/App.xaml b/App.xaml index bffea81..a9025ab 100644 --- a/App.xaml +++ b/App.xaml @@ -5,7 +5,8 @@ - + + diff --git a/Icons.xaml b/Icons.xaml new file mode 100644 index 0000000..848e067 --- /dev/null +++ b/Icons.xaml @@ -0,0 +1,483 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Images/Clear.svg b/Images/Clear.svg new file mode 100644 index 0000000..a93f38f --- /dev/null +++ b/Images/Clear.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Images/Clear.xaml b/Images/Clear.xaml new file mode 100644 index 0000000..85ad8ee --- /dev/null +++ b/Images/Clear.xaml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Images/Connect.png b/Images/Connect.png deleted file mode 100644 index 1fba021..0000000 Binary files a/Images/Connect.png and /dev/null differ diff --git a/Images/Connect.svg b/Images/Connect.svg new file mode 100644 index 0000000..cc7e08e --- /dev/null +++ b/Images/Connect.svg @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Images/Connect.xaml b/Images/Connect.xaml new file mode 100644 index 0000000..a31ac6f --- /dev/null +++ b/Images/Connect.xaml @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Images/Disconnect.png b/Images/Disconnect.png deleted file mode 100644 index e86d993..0000000 Binary files a/Images/Disconnect.png and /dev/null differ diff --git a/Images/Disconnect.svg b/Images/Disconnect.svg new file mode 100644 index 0000000..34bc7c2 --- /dev/null +++ b/Images/Disconnect.svg @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Images/Disconnect.xaml b/Images/Disconnect.xaml new file mode 100644 index 0000000..66d8822 --- /dev/null +++ b/Images/Disconnect.xaml @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Model/IConnection.cs b/Model/IConnection.cs index a0967e8..394a721 100644 --- a/Model/IConnection.cs +++ b/Model/IConnection.cs @@ -2,6 +2,29 @@ namespace PettingZoo.Model { + public enum ConnectionStatus + { + Disconnected, + Connecting, + Connected, + Error + } + + + public class StatusChangedEventArgs : EventArgs + { + public ConnectionStatus Status { get; private set; } + public string Context { get; private set; } + + + public StatusChangedEventArgs(ConnectionStatus status, string context) + { + Status = status; + Context = context; + } + } + + public class MessageReceivedEventArgs : EventArgs { public MessageInfo MessageInfo { get; private set; } @@ -14,8 +37,10 @@ namespace PettingZoo.Model } + public interface IConnection : IDisposable { + event EventHandler StatusChanged; event EventHandler MessageReceived; } } diff --git a/Model/RabbitMQClientConnection.cs b/Model/RabbitMQClientConnection.cs index 2978baf..0b9c4b5 100644 --- a/Model/RabbitMQClientConnection.cs +++ b/Model/RabbitMQClientConnection.cs @@ -12,11 +12,14 @@ namespace PettingZoo.Model { public class RabbitMQClientConnection : IConnection { + private const int ConnectRetryDelay = 5000; + private readonly CancellationTokenSource connectionTaskToken; private RabbitMQ.Client.IConnection connection; private IModel model; + public event EventHandler StatusChanged; public event EventHandler MessageReceived; @@ -44,6 +47,9 @@ namespace PettingZoo.Model connection.Dispose(); connection = null; } + + StatusChanged = null; + MessageReceived = null; } @@ -58,18 +64,34 @@ namespace PettingZoo.Model Password = connectionInfo.Password }; - // ToDo exception handling - connection = factory.CreateConnection(); - model = connection.CreateModel(); + var statusContext = String.Format(@"{0}:{1}{2}", connectionInfo.Host, connectionInfo.Port, connectionInfo.VirtualHost); - var queueName = model.QueueDeclare().QueueName; - model.QueueBind(queueName, connectionInfo.Exchange, connectionInfo.RoutingKey); + while (!cancellationToken.IsCancellationRequested) + { + DoStatusChanged(ConnectionStatus.Connecting, statusContext); + try + { + connection = factory.CreateConnection(); + model = connection.CreateModel(); + + var queueName = model.QueueDeclare().QueueName; + model.QueueBind(queueName, connectionInfo.Exchange, connectionInfo.RoutingKey); - var consumer = new EventingBasicConsumer(model); - consumer.Received += ClientReceived; + var consumer = new EventingBasicConsumer(model); + consumer.Received += ClientReceived; - model.BasicConsume(queueName, true, consumer); + model.BasicConsume(queueName, true, consumer); + DoStatusChanged(ConnectionStatus.Connected, statusContext); + + break; + } + catch (Exception e) + { + DoStatusChanged(ConnectionStatus.Error, e.Message); + Task.Delay(ConnectRetryDelay, cancellationToken).Wait(cancellationToken); + } + } } @@ -90,6 +112,13 @@ namespace PettingZoo.Model } + private void DoStatusChanged(ConnectionStatus status, string context = null) + { + if (StatusChanged != null) + StatusChanged(this, new StatusChangedEventArgs(status, context)); + } + + private static Dictionary ConvertProperties(IBasicProperties basicProperties) { var properties = new Dictionary(); diff --git a/PettingZoo.csproj b/PettingZoo.csproj index cc251c1..ed207e9 100644 --- a/PettingZoo.csproj +++ b/PettingZoo.csproj @@ -92,6 +92,10 @@ MSBuild:Compile Designer + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -177,10 +181,6 @@ false - - - - diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs index abbcb26..ba0c262 100644 --- a/Properties/Resources.Designer.cs +++ b/Properties/Resources.Designer.cs @@ -212,5 +212,41 @@ namespace PettingZoo.Properties { return ResourceManager.GetString("PropertyValue", resourceCulture); } } + + /// + /// Looks up a localized string similar to Connected. + /// + public static string StatusConnected { + get { + return ResourceManager.GetString("StatusConnected", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Connecting to {0}.... + /// + public static string StatusConnecting { + get { + return ResourceManager.GetString("StatusConnecting", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Disconnected. + /// + public static string StatusDisconnected { + get { + return ResourceManager.GetString("StatusDisconnected", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error: {0}. + /// + public static string StatusError { + get { + return ResourceManager.GetString("StatusError", resourceCulture); + } + } } } diff --git a/Properties/Resources.resx b/Properties/Resources.resx index 4758649..e9c49e4 100644 --- a/Properties/Resources.resx +++ b/Properties/Resources.resx @@ -168,4 +168,16 @@ Value + + Connected + + + Connecting to {0}... + + + Disconnected + + + Error: {0} + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..bfe49bb --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +# Petting Zoo +##### A RabbitMQ live message viewer + +ToDo: explain how it brings you coffee, fame and world peace. Or maybe just makes watching the messages flow slightly more comfortable. + + +#### Icons + +Icons are from the Interaction Assets pack by Madebyoliver + + +Designed by Freepik and distributed by Flaticon \ No newline at end of file diff --git a/View/ConnectionWindow.xaml b/View/ConnectionWindow.xaml index 29b3776..700f928 100644 --- a/View/ConnectionWindow.xaml +++ b/View/ConnectionWindow.xaml @@ -40,6 +40,7 @@