# HG changeset patch # User adminsh@apollo # Date 1332356459 0 # Node ID 96fdf58e05b44e95033a84a221d37eeadd36588e # Parent 045dac5713399ddf9d56a58d1db66447cbffd8fd Server working with sockets and rabbitmq diff -r 045dac571339 -r 96fdf58e05b4 Messaging/Common/Binding/BindingErrorTraceListener.cs --- a/Messaging/Common/Binding/BindingErrorTraceListener.cs Wed Mar 21 15:39:53 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -// http://www.switchonthecode.com/tutorials/wpf-snippet-detecting-binding-errors - -using System.Diagnostics; -using System.Text; -using System.Windows; - -namespace Common.Binding -{ - public class BindingErrorTraceListener : DefaultTraceListener - { - private static BindingErrorTraceListener _listener; - - - private readonly StringBuilder _message = new StringBuilder(); - - private BindingErrorTraceListener() - { - } - - public override void Write(string message) - { - _message.Append(message); - } - - public override void WriteLine(string message) - { - _message.Append(message); - - var final = _message.ToString(); - _message.Length = 0; - - MessageBox.Show(final, - "Binding Error", - MessageBoxButton.OK, - MessageBoxImage.Error); - } - - public static void CloseTrace() - { - if (_listener == null) - { - return; - } - - _listener.Flush(); - _listener.Close(); - PresentationTraceSources.DataBindingSource.Listeners.Remove(_listener); - _listener = null; - } - - [Conditional("DEBUG")] - public static void SetTrace() - { - SetTrace(SourceLevels.Error, TraceOptions.None); - } - - public static void SetTrace(SourceLevels level, TraceOptions options) - { - if (_listener == null) - { - _listener = new BindingErrorTraceListener(); - PresentationTraceSources.DataBindingSource.Listeners.Add(_listener); - } - - _listener.TraceOutputOptions = options; - PresentationTraceSources.DataBindingSource.Switch.Level = level; - } - } -} diff -r 045dac571339 -r 96fdf58e05b4 Messaging/Common/Common.csproj --- a/Messaging/Common/Common.csproj Wed Mar 21 15:39:53 2012 +0000 +++ b/Messaging/Common/Common.csproj Wed Mar 21 19:00:59 2012 +0000 @@ -42,14 +42,15 @@ - + - + MessageTile.xaml + diff -r 045dac571339 -r 96fdf58e05b4 Messaging/Common/Controls/MessageTile.xaml --- a/Messaging/Common/Controls/MessageTile.xaml Wed Mar 21 15:39:53 2012 +0000 +++ b/Messaging/Common/Controls/MessageTile.xaml Wed Mar 21 19:00:59 2012 +0000 @@ -3,9 +3,9 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + Name="CustomMessageTile" Width="200" Height="200" - DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}" mc:Ignorable="d"> @@ -27,8 +27,8 @@ Margin="10,10,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" - Source="{Binding Path=DisplayIcon, - Mode=OneWay, + Source="{Binding DisplayIcon, + ElementName=CustomMessageTile, UpdateSourceTrigger=PropertyChanged}" Stretch="None" /> @@ -39,9 +39,10 @@ Margin="0,0,10,0" HorizontalAlignment="Right" FontSize="48" - Text="{Binding Path=DisplayCount, + Text="{Binding DisplayCount, StringFormat=N0, Mode=TwoWay, + ElementName=CustomMessageTile, UpdateSourceTrigger=PropertyChanged}" /> diff -r 045dac571339 -r 96fdf58e05b4 Messaging/Common/Controls/MessageTile.xaml.cs --- a/Messaging/Common/Controls/MessageTile.xaml.cs Wed Mar 21 15:39:53 2012 +0000 +++ b/Messaging/Common/Controls/MessageTile.xaml.cs Wed Mar 21 19:00:59 2012 +0000 @@ -46,14 +46,14 @@ DependencyProperty.Register("DisplayCount", typeof(int), typeof(MessageTile), - new PropertyMetadata(0)); + new UIPropertyMetadata(0)); - [Bindable(true)] public int DisplayCount { get { return (int) this.GetValue(DisplayCountProperty); } set { this.SetValue(DisplayCountProperty, value); } } + #endregion #region DisplayText diff -r 045dac571339 -r 96fdf58e05b4 Messaging/Common/Messages/LogMessage.cs --- a/Messaging/Common/Messages/LogMessage.cs Wed Mar 21 15:39:53 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -using GalaSoft.MvvmLight.Messaging; - -namespace Common.Messages -{ - public class LogMessage : MessageBase - { - public string Body { get; set; } - } -} diff -r 045dac571339 -r 96fdf58e05b4 Messaging/Common/Messages/LogMessages.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Messaging/Common/Messages/LogMessages.cs Wed Mar 21 19:00:59 2012 +0000 @@ -0,0 +1,21 @@ +using GalaSoft.MvvmLight.Messaging; + +namespace Common.Messages +{ + public class LogMessage : MessageBase + { + public string Body { get; set; } + } + + public class SocketLogMessage : LogMessage + { + } + + public class RabbitLogMessage : LogMessage + { + } + + public class RabbitProtoLogMessage : LogMessage + { + } +} diff -r 045dac571339 -r 96fdf58e05b4 Messaging/Common/Settings.cs --- a/Messaging/Common/Settings.cs Wed Mar 21 15:39:53 2012 +0000 +++ b/Messaging/Common/Settings.cs Wed Mar 21 19:00:59 2012 +0000 @@ -2,7 +2,9 @@ { public class Settings { - public const int SocketsPortNumber = 10001; + public const int SocketsPortNumber = 5671; + public const int RabbitPortNumber = 5672; + public const int RabbitProtoPortNumber = 5673; public const string QueueName = "Queue#1"; //public const string Uri = @"amqp://user:pass@localhost:5672/vhost\"; } diff -r 045dac571339 -r 96fdf58e05b4 Messaging/Common/Xaml/BindingErrorTraceListener.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Messaging/Common/Xaml/BindingErrorTraceListener.cs Wed Mar 21 19:00:59 2012 +0000 @@ -0,0 +1,69 @@ +// http://www.switchonthecode.com/tutorials/wpf-snippet-detecting-binding-errors + +using System.Diagnostics; +using System.Text; +using System.Windows; + +namespace Common.Xaml +{ + public class BindingErrorTraceListener : DefaultTraceListener + { + private static BindingErrorTraceListener _listener; + + + private readonly StringBuilder _message = new StringBuilder(); + + private BindingErrorTraceListener() + { + } + + public override void Write(string message) + { + _message.Append(message); + } + + public override void WriteLine(string message) + { + _message.Append(message); + + var final = _message.ToString(); + _message.Length = 0; + + MessageBox.Show(final, + "Binding Error", + MessageBoxButton.OK, + MessageBoxImage.Error); + } + + public static void CloseTrace() + { + if (_listener == null) + { + return; + } + + _listener.Flush(); + _listener.Close(); + PresentationTraceSources.DataBindingSource.Listeners.Remove(_listener); + _listener = null; + } + + [Conditional("DEBUG")] + public static void SetTrace() + { + SetTrace(SourceLevels.Error, TraceOptions.None); + } + + public static void SetTrace(SourceLevels level, TraceOptions options) + { + if (_listener == null) + { + _listener = new BindingErrorTraceListener(); + PresentationTraceSources.DataBindingSource.Listeners.Add(_listener); + } + + _listener.TraceOutputOptions = options; + PresentationTraceSources.DataBindingSource.Switch.Level = level; + } + } +} diff -r 045dac571339 -r 96fdf58e05b4 Messaging/Common/Xaml/XamlHelper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Messaging/Common/Xaml/XamlHelper.cs Wed Mar 21 19:00:59 2012 +0000 @@ -0,0 +1,34 @@ +using System.Windows; +using System.Windows.Controls; + +namespace Common.Xaml +{ + public static class XamlHelper + { + public static bool GetAutoScroll(DependencyObject obj) + { + return (bool) obj.GetValue(AutoScrollProperty); + } + + public static void SetAutoScroll(DependencyObject obj, bool value) + { + obj.SetValue(AutoScrollProperty, value); + } + + public static readonly DependencyProperty AutoScrollProperty = + DependencyProperty.RegisterAttached("AutoScroll", + typeof(bool), + typeof(XamlHelper), + new PropertyMetadata(false, AutoScrollPropertyChanged)); + + private static void AutoScrollPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var scrollViewer = d as ScrollViewer; + + if (scrollViewer != null && (bool)e.NewValue) + { + scrollViewer.ScrollToBottom(); + } + } + } +} diff -r 045dac571339 -r 96fdf58e05b4 Messaging/Libs/RabbitMq.2.6.1.0/RabbitMQ.Client.dll Binary file Messaging/Libs/RabbitMq.2.6.1.0/RabbitMQ.Client.dll has changed diff -r 045dac571339 -r 96fdf58e05b4 Messaging/Server/App.xaml.cs --- a/Messaging/Server/App.xaml.cs Wed Mar 21 15:39:53 2012 +0000 +++ b/Messaging/Server/App.xaml.cs Wed Mar 21 19:00:59 2012 +0000 @@ -1,5 +1,5 @@ using System.Windows; -using Common.Binding; +using Common.Xaml; namespace Server { diff -r 045dac571339 -r 96fdf58e05b4 Messaging/Server/EndPoints/BaseEndPoint.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Messaging/Server/EndPoints/BaseEndPoint.cs Wed Mar 21 19:00:59 2012 +0000 @@ -0,0 +1,162 @@ +using System; +using System.Threading.Tasks; +using Common.Messages; +using GalaSoft.MvvmLight; +using Server.Interfaces; + +namespace Server.EndPoints +{ + public abstract class BaseEndPoint : ObservableObject + { + #region Fields + + private readonly IListener _listener; + + #endregion + + #region Constructor + + protected BaseEndPoint(IListener listener) + { + _listener = listener; + } + + #endregion + + public virtual void Init() + { + + } + + protected void LogMessageReceived(LogMessage m) + { + this.DisplayLog = DisplayLog + Environment.NewLine + m.Body; + } + + #region Properties + + #region IsListening + + public const string IsListeningPropertyName = "IsListening"; + private bool _isListening; + public bool IsListening + { + get { return _isListening; } + set + { + if (_isListening == value) return; + _isListening = value; + RaisePropertyChanged(() => IsListening); + ToggleListener(); + } + } + + #endregion + + #region DisplayText + + public const string DisplayTextPropertyName = "DisplayText"; + private string _displayText; + public string DisplayText + { + get { return _displayText; } + set + { + if (_displayText == value) return; + _displayText = value; + RaisePropertyChanged(() => DisplayText); + } + } + + #endregion + + #region DisplayCount + + public const string DisplayCountPropertyName = "DisplayCount"; + private int _displayCount; + public int DisplayCount + { + get { return _displayCount; } + set + { + if (_displayCount == value) return; + _displayCount = value; + RaisePropertyChanged(() => DisplayCount); + } + } + #endregion + + #region DisplayLog + + public const string DisplayLogPropertyName = "DisplayLog"; + private string _displayLog = string.Empty; + public string DisplayLog + { + get { return _displayLog; } + set + { + if (_displayLog == value) return; + _displayLog = value; + RaisePropertyChanged(() => DisplayLog); + IsLogChanged = true; + } + } + + #endregion + + #region IsLogChanged + + public const string IsLogChangedPropertyName = "IsLogChanged"; + private bool _isLogChanged; + public bool IsLogChanged + { + get { return _isLogChanged; } + set + { + if (_isLogChanged == value) return; + _isLogChanged = value; + RaisePropertyChanged(() => IsLogChanged); + } + } + + #endregion + + #region ToolTip + + public const string ToolTipPropertyName = "ToolTip"; + private string _toolTip = string.Empty; + public string ToolTip + { + get { return _toolTip; } + set + { + if (_toolTip == value) return; + _toolTip = value; + RaisePropertyChanged(() => ToolTip); + } + } + + #endregion + + #endregion + + #region Commands + + + private void ToggleListener() + { + if (null == _listener) return; + + if (_listener.IsListening) + { + Task.Factory.StartNew(_listener.Stop); + } + else + { + Task.Factory.StartNew(_listener.Start); + } + } + + #endregion + } +} diff -r 045dac571339 -r 96fdf58e05b4 Messaging/Server/EndPoints/RabbitEndPoint.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Messaging/Server/EndPoints/RabbitEndPoint.cs Wed Mar 21 19:00:59 2012 +0000 @@ -0,0 +1,19 @@ +using Common.Messages; +using GalaSoft.MvvmLight.Messaging; +using Server.Interfaces; + +namespace Server.EndPoints +{ + public class RabbitEndPoint : BaseEndPoint + { + public RabbitEndPoint(IListener listener) : base(listener) + { + Init(); + } + + public override sealed void Init() + { + Messenger.Default.Register(this, LogMessageReceived); + } + } +} diff -r 045dac571339 -r 96fdf58e05b4 Messaging/Server/EndPoints/RabbitProtoEndPoint.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Messaging/Server/EndPoints/RabbitProtoEndPoint.cs Wed Mar 21 19:00:59 2012 +0000 @@ -0,0 +1,19 @@ +using Common.Messages; +using GalaSoft.MvvmLight.Messaging; +using Server.Interfaces; + +namespace Server.EndPoints +{ + public class RabbitProtoEndPoint : BaseEndPoint + { + public RabbitProtoEndPoint(IListener listener) : base(listener) + { + Init(); + } + + public override sealed void Init() + { + Messenger.Default.Register(this, LogMessageReceived); + } + } +} diff -r 045dac571339 -r 96fdf58e05b4 Messaging/Server/EndPoints/SocketEndPoint.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Messaging/Server/EndPoints/SocketEndPoint.cs Wed Mar 21 19:00:59 2012 +0000 @@ -0,0 +1,19 @@ +using Common.Messages; +using GalaSoft.MvvmLight.Messaging; +using Server.Interfaces; + +namespace Server.EndPoints +{ + public class SocketEndPoint : BaseEndPoint + { + public SocketEndPoint(IListener listener) : base(listener) + { + Init(); + } + + public override sealed void Init() + { + Messenger.Default.Register(this, LogMessageReceived); + } + } +} diff -r 045dac571339 -r 96fdf58e05b4 Messaging/Server/Listeners/AsyncSocketListener.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Messaging/Server/Listeners/AsyncSocketListener.cs Wed Mar 21 19:00:59 2012 +0000 @@ -0,0 +1,197 @@ +using System; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading; +using Common.Messages; +using GalaSoft.MvvmLight.Messaging; +using Server.Interfaces; + +namespace Server.Listeners +{ + public class AsyncSocketListener : IListener + { + public bool IsListening { get; set; } + private readonly int _portNumber; + + // Thread signal. + public static ManualResetEvent AllDone = new ManualResetEvent(false); + + public AsyncSocketListener(int portNumber) + { + IsListening = false; + _portNumber = portNumber; + } + + public void Start() + { + Messenger.Default.Send(new SocketLogMessage() { Body = "Opening connection..." }); + + // Data buffer for incoming data. + var bytes = new Byte[1024]; + + // Establish the local endpoint for the socket + var ipHostInfo = Dns.GetHostEntry(Dns.GetHostName()); + var ipAddress = ipHostInfo.AddressList[2]; + var localEndPoint = new IPEndPoint(ipAddress, _portNumber); + + // Create a TCP/IP socket. + using(var listener = new Socket( + AddressFamily.InterNetwork, + SocketType.Stream, + ProtocolType.Tcp)) + { + + // Bind the socket to the local endpoint and listen for incoming connections. + try + { + listener.Bind(localEndPoint); + listener.Listen(100); + IsListening = true; + + Messenger.Default.Send(new SocketLogMessage() { Body = "Connection opened" }); + + while (IsListening) + { + // Set the event to nonsignaled state. + AllDone.Reset(); + + // Start an asynchronous socket to listen for connections. + Messenger.Default.Send(new SocketLogMessage() { Body = "Waiting for a connection..." }); + + listener.BeginAccept( + AcceptCallback, + listener); + + // Wait until a connection is made before continuing. + AllDone.WaitOne(); + } + } + catch (Exception e) + { + Messenger.Default.Send(new SocketLogMessage() { Body = e.Message }); + } + } + } + + public void AcceptCallback(IAsyncResult ar) + { + // Signal the main thread to continue. + AllDone.Set(); + + // Get the socket that handles the client request. + var listener = (Socket) ar.AsyncState; + var handler = listener.EndAccept(ar); + + // Create the state object. + var state = new StateObject {WorkSocket = handler}; + + handler.BeginReceive( + state.Buffer, + 0, + StateObject.BufferSize, + 0, + ReadCallback, + state); + } + + public void ReadCallback(IAsyncResult ar) + { + var content = String.Empty; + + // Retrieve the state object and the handler socket + // from the asynchronous state object. + var state = (StateObject)ar.AsyncState; + var handler = state.WorkSocket; + + // Read data from the client socket. + var bytesRead = handler.EndReceive(ar); + + if (bytesRead <= 0) return; + + // There might be more data, so store the data received so far. + state.Sb.Append( + Encoding.ASCII.GetString( + state.Buffer, + 0, + bytesRead)); + + // Check for end-of-file tag. If it is not there, read + // more data. + content = state.Sb.ToString(); + if (content.IndexOf("") > -1) + { + // All the data has been read from the + // client. Display it on the console. + + Messenger.Default.Send( + new SocketLogMessage() + { + Body = string.Format( + "Read {0} bytes from socket. \n Data : {1}", + content.Length, + content) + }); + + // Echo the data back to the client. + Send(handler, "The following message was received: " + content); + } + else + { + // Not all data received. Get more. + handler.BeginReceive( + state.Buffer, + 0, + StateObject.BufferSize, + 0, + ReadCallback, + state); + } + } + + private void Send(Socket handler, String data) + { + // Convert the string data to byte data using ASCII encoding. + var byteData = Encoding.ASCII.GetBytes(data); + + // Begin sending the data to the remote device. + handler.BeginSend( + byteData, + 0, + byteData.Length, + 0, + SendCallback, + handler); + } + + private void SendCallback(IAsyncResult ar) + { + try + { + // Retrieve the socket from the state object. + var handler = (Socket)ar.AsyncState; + + // Complete sending the data to the remote device. + var bytesSent = handler.EndSend(ar); + + Messenger.Default.Send(new SocketLogMessage() { Body = string.Format("Sent {0} bytes to client.", bytesSent) }); + + handler.Shutdown(SocketShutdown.Both); + handler.Close(); + } + catch (Exception e) + { + Messenger.Default.Send(new SocketLogMessage() { Body = e.Message }); + } + } + + public void Stop() + { + if (IsListening == false) return; + + Messenger.Default.Send(new SocketLogMessage() { Body = "Closing connection..." }); + IsListening = false; + Messenger.Default.Send(new SocketLogMessage() { Body = "Connection closed." }); + } + } +} \ No newline at end of file diff -r 045dac571339 -r 96fdf58e05b4 Messaging/Server/Listeners/RabbitQueueListener.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Messaging/Server/Listeners/RabbitQueueListener.cs Wed Mar 21 19:00:59 2012 +0000 @@ -0,0 +1,75 @@ +using System; +using System.Diagnostics; +using System.Text; +using Common.Messages; +using GalaSoft.MvvmLight.Messaging; +using RabbitMQ.Client; +using RabbitMQ.Client.Events; +using RabbitMQ.Client.MessagePatterns; +using Server.Interfaces; + +namespace Server.Listeners +{ + class RabbitQueueListener : IListener + { + public bool IsListening { get; set; } + private readonly int _port; + + public RabbitQueueListener(int port) + { + _port = port; + } + + public void Start() + { + try + { + var serverAddress = "localhost:" + _port; + + var connectionFactory = new ConnectionFactory { Address = serverAddress }; + + using (var connection = connectionFactory.CreateConnection()) + { + using (var channel = connection.CreateModel()) + { + Log("Creating a queue and binding it to amq.direct"); + string queueName = channel.QueueDeclare(); + + channel.QueueBind(queueName, "amq.direct", queueName, null); + Log(string.Format("Done. Created queue {0} and bound to amq.direct\n", queueName)); + + using (var subscription = new Subscription(channel, queueName)) + { + IsListening = true; + while (IsListening) + { + foreach (BasicDeliverEventArgs eventArgs in subscription) + { + Log(Encoding.UTF8.GetString(eventArgs.Body)); + subscription.Ack(); + } + } + } + } + } + } + catch (Exception e) + { + Log(e.Message); + } + } + + public void Stop() + { + Log("Stopping listening..."); + IsListening = false; + Log("Listening stopped."); + } + + private void Log(string message) + { + Debug.WriteLine(message); + Messenger.Default.Send(new RabbitLogMessage() { Body = message }); + } + } +} diff -r 045dac571339 -r 96fdf58e05b4 Messaging/Server/Listeners/StateObject.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Messaging/Server/Listeners/StateObject.cs Wed Mar 21 19:00:59 2012 +0000 @@ -0,0 +1,21 @@ +using System.Net.Sockets; +using System.Text; + +namespace Server.Listeners +{ + // State object for reading client data asynchronously + public class StateObject + { + // Client socket. + public Socket WorkSocket; + + // Size of receive buffer. + public const int BufferSize = 1024; + + // Receive buffer. + public byte[] Buffer = new byte[BufferSize]; + + // Received data string. + public StringBuilder Sb = new StringBuilder(); + } +} diff -r 045dac571339 -r 96fdf58e05b4 Messaging/Server/Server.csproj --- a/Messaging/Server/Server.csproj Wed Mar 21 15:39:53 2012 +0000 +++ b/Messaging/Server/Server.csproj Wed Mar 21 19:00:59 2012 +0000 @@ -57,6 +57,10 @@ ..\Libs\Elysium.Theme.1.3\Microsoft.Windows.Shell.dll + + False + ..\Libs\RabbitMq.2.6.1.0\RabbitMQ.Client.dll + ..\Libs\Elysium.Theme.1.3\System.Windows.Interactivity.dll @@ -76,11 +80,15 @@ Designer + + + + - - + + MSBuild:Compile Designer @@ -89,7 +97,7 @@ App.xaml Code - + MainWindow.xaml Code @@ -128,6 +136,7 @@ +