Mercurial > silverbladetech
changeset 27:96fdf58e05b4
Server working with sockets and rabbitmq
line wrap: on
line diff
--- 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; - } - } -}
--- 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 @@ <Reference Include="WindowsBase" /> </ItemGroup> <ItemGroup> - <Compile Include="Binding\BindingErrorTraceListener.cs" /> + <Compile Include="Xaml\BindingErrorTraceListener.cs" /> <Compile Include="Logger\Log.cs" /> - <Compile Include="Messages\LogMessage.cs" /> + <Compile Include="Messages\LogMessages.cs" /> <Compile Include="Controls\MessageTile.xaml.cs"> <DependentUpon>MessageTile.xaml</DependentUpon> </Compile> <Compile Include="Settings.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Xaml\XamlHelper.cs" /> </ItemGroup> <ItemGroup> <Page Include="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"> <Grid> @@ -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}" /> <TextBlock Name="tbTitle" @@ -53,8 +54,9 @@ HorizontalAlignment="Right" VerticalAlignment="Bottom" FontSize="24" - Text="{Binding Path=DisplayText, + Text="{Binding DisplayText, Mode=TwoWay, + ElementName=CustomMessageTile, UpdateSourceTrigger=PropertyChanged}" TextWrapping="Wrap" />
--- 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
--- 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; } - } -}
--- /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 + { + } +}
--- 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\"; }
--- /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; + } + } +}
--- /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(); + } + } + } +}
--- 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 {
--- /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 + } +}
--- /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<RabbitLogMessage>(this, LogMessageReceived); + } + } +}
--- /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<RabbitProtoLogMessage>(this, LogMessageReceived); + } + } +}
--- /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<SocketLogMessage>(this, LogMessageReceived); + } + } +}
--- /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("<EOF>") > -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
--- /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 }); + } + } +}
--- /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(); + } +}
--- 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 @@ <Reference Include="Microsoft.Windows.Shell, Version=3.5.41019.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <HintPath>..\Libs\Elysium.Theme.1.3\Microsoft.Windows.Shell.dll</HintPath> </Reference> + <Reference Include="RabbitMQ.Client, Version=2.6.1.0, Culture=neutral, PublicKeyToken=89e7d7c5feba84ce, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\Libs\RabbitMq.2.6.1.0\RabbitMQ.Client.dll</HintPath> + </Reference> <Reference Include="System" /> <Reference Include="System.Windows.Interactivity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <HintPath>..\Libs\Elysium.Theme.1.3\System.Windows.Interactivity.dll</HintPath> @@ -76,11 +80,15 @@ <SubType>Designer</SubType> </ApplicationDefinition> <Compile Include="Converters\ToggleButtonToTextConverter.cs" /> + <Compile Include="EndPoints\RabbitEndPoint.cs" /> + <Compile Include="EndPoints\RabbitProtoEndPoint.cs" /> + <Compile Include="EndPoints\SocketEndPoint.cs" /> <Compile Include="Interfaces\IListener.cs" /> <Compile Include="Locator.cs" /> + <Compile Include="Listeners\RabbitQueueListener.cs" /> <Compile Include="UI\MainWindowViewModel.cs" /> - <Compile Include="Sockets\StateObject.cs" /> - <Compile Include="UI\MessagingEndpoint.cs" /> + <Compile Include="Listeners\StateObject.cs" /> + <Compile Include="EndPoints\BaseEndPoint.cs" /> <Page Include="UI\MainWindow.xaml"> <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> @@ -89,7 +97,7 @@ <DependentUpon>App.xaml</DependentUpon> <SubType>Code</SubType> </Compile> - <Compile Include="Sockets\AsyncSocketListener.cs" /> + <Compile Include="Listeners\AsyncSocketListener.cs" /> <Compile Include="UI\MainWindow.xaml.cs"> <DependentUpon>MainWindow.xaml</DependentUpon> <SubType>Code</SubType> @@ -128,6 +136,7 @@ <ItemGroup> <Resource Include="UI\mail.ico" /> </ItemGroup> + <ItemGroup /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets.
--- a/Messaging/Server/Sockets/AsyncSocketListener.cs Wed Mar 21 15:39:53 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,182 +0,0 @@ -using System; -using System.Net; -using System.Net.Sockets; -using System.Text; -using System.Threading; -using Common; -using Common.Logger; -using Server.Interfaces; - -namespace Server.Sockets -{ - public class AsyncSocketListener : IListener - { - public bool IsListening { get; set; } - private int _portNumber; - - // Thread signal. - public static ManualResetEvent AllDone = new ManualResetEvent(false); - - public AsyncSocketListener(int portNumber) - { - IsListening = false; - _portNumber = portNumber; - } - - public void Start() - { - // 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[0]; - var localEndPoint = new IPEndPoint(ipAddress, _portNumber); - - // Create a TCP/IP socket. - 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; - - while (IsListening) - { - // Set the event to nonsignaled state. - AllDone.Reset(); - - // Start an asynchronous socket to listen for connections. - Log.Write("Waiting for a connection..."); - - listener.BeginAccept( - AcceptCallback, - listener); - - // Wait until a connection is made before continuing. - AllDone.WaitOne(); - } - } - catch (Exception e) - { - Log.Write(e.ToString()); - } - } - - 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("<EOF>") > -1) - { - // All the data has been read from the - // client. Display it on the console. - Log.Write( - 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); - Log.Write(string.Format("Sent {0} bytes to client.", bytesSent)); - - handler.Shutdown(SocketShutdown.Both); - handler.Close(); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - } - } - - public void Stop() - { - IsListening = false; - } - } -} \ No newline at end of file
--- a/Messaging/Server/Sockets/StateObject.cs Wed Mar 21 15:39:53 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -using System.Net.Sockets; -using System.Text; - -namespace Server.Sockets -{ - // 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(); - } -}
--- a/Messaging/Server/UI/MainWindow.xaml Wed Mar 21 15:39:53 2012 +0000 +++ b/Messaging/Server/UI/MainWindow.xaml Wed Mar 21 19:00:59 2012 +0000 @@ -4,6 +4,7 @@ xmlns:c="clr-namespace:Common.Controls;assembly=Common" xmlns:converters="clr-namespace:Server.Converters" xmlns:metro="http://schemas.codeplex.com/elysium/theme" + xmlns:Xaml="clr-namespace:Common.Xaml;assembly=Common" Title="Messaging Server" Width="700" Height="475" @@ -40,23 +41,25 @@ <ToggleButton Grid.Row="0" Grid.Column="1" Margin="10,10,10,0" - Content="{Binding SocketEndPoint.IsListening, + Content="{Binding RabbitEndPoint.IsListening, Converter={converters:ToggleButtonToTextConverter}}" - IsChecked="{Binding SocketEndPoint.IsListening}" + IsChecked="{Binding RabbitEndPoint.IsListening}" IsEnabled="True" /> <ToggleButton Grid.Row="0" Grid.Column="2" Margin="10,10,10,0" - Content="{Binding SocketEndPoint.IsListening, + Content="{Binding RabbitProtoEndPoint.IsListening, Converter={converters:ToggleButtonToTextConverter}}" - IsChecked="{Binding SocketEndPoint.IsListening}" + IsChecked="{Binding RabbitProtoEndPoint.IsListening}" IsEnabled="True" /> <c:MessageTile Grid.Row="1" Grid.Column="0" Background="{StaticResource MetroPurpleBrush}" - DisplayCount="{Binding SocketEndPoint.DisplayCount, Mode= TwoWay, UpdateSourceTrigger=PropertyChanged}" + DisplayCount="{Binding SocketEndPoint.DisplayCount, + Mode=TwoWay, + UpdateSourceTrigger=PropertyChanged}" DisplayIcon="{StaticResource Mail}" DisplayText="{Binding SocketEndPoint.DisplayText}" Foreground="White" @@ -65,45 +68,49 @@ <c:MessageTile Grid.Row="1" Grid.Column="1" Background="{StaticResource MetroGreenBrush}" - DisplayCount="{Binding SocketEndPoint.DisplayCount}" + DisplayCount="{Binding RabbitEndPoint.DisplayCount}" DisplayIcon="{StaticResource Mail}" - DisplayText="{Binding DisplayText}" + DisplayText="{Binding RabbitEndPoint.DisplayText}" Foreground="White" - ToolTip="{Binding SocketEndPoint.ToolTip}" /> + ToolTip="{Binding RabbitEndPoint.ToolTip}" /> <c:MessageTile Grid.Row="1" Grid.Column="2" Background="{StaticResource MetroOrangeBrush}" - DisplayCount="{Binding SocketEndPoint.DisplayCount}" + DisplayCount="{Binding RabbitProtoEndPoint.DisplayCount}" DisplayIcon="{StaticResource Mail}" - DisplayText="{Binding SocketEndPoint.DisplayText}" + DisplayText="{Binding RabbitProtoEndPoint.DisplayText}" Foreground="White" - ToolTip="{Binding SocketEndPoint.ToolTip}" /> - - <TextBlock Grid.Row="2" - Grid.Column="0" - Margin="10" - Background="{StaticResource MetroGrayBrush}" - Padding="10" - Text="{Binding SocketEndPoint.DisplayLog}" - TextWrapping="Wrap" /> - - <TextBlock Grid.Row="2" - Grid.Column="1" - Margin="10" - Background="{StaticResource MetroGrayBrush}" - Padding="10" - Text="{Binding SocketEndPoint.DisplayLog}" - TextWrapping="WrapWithOverflow" /> - - <TextBlock Grid.Row="2" - Grid.Column="2" - Margin="10" - Background="{StaticResource MetroGrayBrush}" - Padding="10" - Text="{Binding SocketEndPoint.DisplayLog}" - TextWrapping="WrapWithOverflow" /> - + ToolTip="{Binding RabbitProtoEndPoint.ToolTip}" /> + <ScrollViewer Grid.Row="2" + Grid.Column="0" + Xaml:XamlHelper.AutoScroll="{Binding SocketEndPoint.IsLogChanged}"> + <TextBlock Margin="10" + Background="{StaticResource MetroGrayBrush}" + Padding="10" + Text="{Binding SocketEndPoint.DisplayLog}" + TextWrapping="Wrap" /> + </ScrollViewer> + <ScrollViewer Grid.Row="2" + Grid.Column="1" + Xaml:XamlHelper.AutoScroll="{Binding RabbitEndPoint.IsLogChanged}"> + <TextBlock Margin="10" + Background="{StaticResource MetroGrayBrush}" + Padding="10" + Text="{Binding RabbitEndPoint.DisplayLog}" + TextWrapping="WrapWithOverflow" /> + </ScrollViewer> + <ScrollViewer Grid.Row="2" + Grid.Column="2" + Xaml:XamlHelper.AutoScroll="{Binding RabbitProtoEndPoint.IsLogChanged}"> + <TextBlock Grid.Row="2" + Grid.Column="2" + Margin="10" + Background="{StaticResource MetroGrayBrush}" + Padding="10" + Text="{Binding RabbitProtoEndPoint.DisplayLog}" + TextWrapping="WrapWithOverflow" /> + </ScrollViewer> <metro:ToggleSwitch Grid.Row="3" Grid.Column="0" Width="80"
--- a/Messaging/Server/UI/MainWindowViewModel.cs Wed Mar 21 15:39:53 2012 +0000 +++ b/Messaging/Server/UI/MainWindowViewModel.cs Wed Mar 21 19:00:59 2012 +0000 @@ -1,11 +1,15 @@ -using System.Windows.Input; +using System; +using System.Windows.Input; using Common; using Common.Logger; +using Common.Messages; using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.Command; using System.Windows; +using GalaSoft.MvvmLight.Messaging; +using Server.EndPoints; using Server.Interfaces; -using Server.Sockets; +using Server.Listeners; namespace Server.UI { @@ -33,48 +37,53 @@ #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 - public ICommand CloseCommand { get; set; } - public MessagingEndPoint SocketEndPoint { get; set; } - public MessagingEndPoint RabbitEndPoint { get; set; } - public MessagingEndPoint RabbitProtoEndPoint { get; set; } + public BaseEndPoint SocketEndPoint { get; set; } + public BaseEndPoint RabbitEndPoint { get; set; } + public BaseEndPoint RabbitProtoEndPoint { get; set; } #region Constructor public MainWindowViewModel() { - IListener listener = new AsyncSocketListener(Settings.SocketsPortNumber); - SocketEndPoint = new MessagingEndPoint(listener) - { - DisplayText = "Async Sockets", - ToolTip = "Listening over TCP/IP on localhost:" + Settings.SocketsPortNumber, - DisplayCount = 9, - DisplayLog = "test for display log" - }; - - DisplayText = "Does this work?!"; + InitSocketEndPoint(Settings.SocketsPortNumber); + InitRabbitEndPoint(Settings.RabbitPortNumber); + InitRabbitProtoEndPoint(Settings.RabbitProtoPortNumber); CloseCommand = new RelayCommand(CloseCommandExecute); + + } + + private void InitSocketEndPoint(int port) + { + IListener listener = new AsyncSocketListener(port); + SocketEndPoint = new SocketEndPoint(listener) + { + DisplayText = "Async Sockets", + ToolTip = "Listening over TCP/IP on socket localhost:" + port + }; } + private void InitRabbitEndPoint(int port) + { + IListener listener = new RabbitQueueListener(port); + RabbitEndPoint = new RabbitEndPoint(listener) + { + DisplayText = "RabbitMQ", + ToolTip = "Listening..." + port + }; + } + + private void InitRabbitProtoEndPoint(int port) + { + IListener listener = null; + RabbitProtoEndPoint = new RabbitProtoEndPoint(listener) + { + DisplayText = "RabbitMQ with Protobuf-net", + ToolTip = "Listening...." + port + }; + } private void CloseCommandExecute() { Log.Write("Closing command executed");
--- a/Messaging/Server/UI/MessagingEndpoint.cs Wed Mar 21 15:39:53 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,128 +0,0 @@ -using System.Windows.Input; -using GalaSoft.MvvmLight; -using GalaSoft.MvvmLight.Command; -using Server.Interfaces; - -namespace Server.UI -{ - public class MessagingEndPoint : ObservableObject - { - #region Fields - - private readonly IListener _listener; - - #endregion - - #region Constructor - - public MessagingEndPoint(IListener listener) - { - _listener = listener; - SwitchCommand = new RelayCommand(SwitchCommandExecute); - } - - #endregion - - #region Properties - - #region IsListening - - public const string IsListeningPropertyName = "IsListening"; - public bool IsListening - { - get { return _listener.IsListening; } - set - { - if (_listener.IsListening == value) return; - _listener.IsListening = value; - RaisePropertyChanged(() => IsListening); - } - } - - #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); - } - } - - #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 - - #region SwitchCommand - - public ICommand SwitchCommand { get; set; } - - private void SwitchCommandExecute() - { - IsListening = !_listener.IsListening; - } - - #endregion - - #endregion - } -}