Click here to Skip to main content
15,886,574 members
Articles / Programming Languages / XML

DotNetMQ: A Complete Message Queue System for .NET

Rate me:
Please Sign up or sign in to vote.
4.94/5 (190 votes)
23 May 2011LGPL331 min read 1.1M   53.8K   490  
A new and independent Open Source Message Queue system that is entirely built in C# and .NET framework 3.5.
/*
DotNetMQ - A Complete Message Broker For .NET
Copyright (C) 2011 Halil ibrahim KALKAN

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

using System;
using System.Reflection;
using System.Threading;
using System.Net.Sockets;
using log4net;
using MDS.Threading;

namespace MDS.Communication.TCPCommunication
{
    /// <summary>
    /// This class is used to listen and accept incoming TCP connection requests on given TCP port.
    /// </summary>
    public class TCPConnectionListener : IRunnable
    {
        #region Events

        /// <summary>
        /// When a client successfully connected the server, this event is raised.
        /// </summary>
        public event TCPClientConnectedHandler TCPClientConnected;

        #endregion

        #region Public properties

        /// <summary>
        /// Listening port number
        /// </summary>
        public int Port { get; private set; }

        #endregion

        #region Private fields

        /// <summary>
        /// Reference to logger
        /// </summary>
        private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        
        /// <summary>
        /// Server socket to listen incoming connection requests.
        /// </summary>
        private TcpListener _listenerSocket;
        
        /// <summary>
        /// The thread to listen socket
        /// </summary>
        private volatile Thread _thread;

        /// <summary>
        /// A flag to control thread's running
        /// </summary>
        private volatile bool _running;

        #endregion

        #region Constructors

        /// <summary>
        /// Creates a new TCPConnectionListener with given tcp port.
        /// </summary>
        /// <param name="port">Listening TCP port no</param>
        public TCPConnectionListener(int port)
        {
            Port = port;
        }

        #endregion

        #region Public methods

        /// <summary>
        /// Starts listening.
        /// </summary>
        public void Start()
        {
            StartSocket();
            _running = true;
            _thread = new Thread(DoListenAsThread);
            _thread.Start();
        }

        /// <summary>
        /// Stops listening.
        /// </summary>
        /// <param name="waitToStop">True, if caller method must wait until running stops.</param>
        public void Stop(bool waitToStop)
        {
            _running = false;
            StopSocket();
            if (waitToStop)
            {
                WaitToStop();
            }
        }

        /// <summary>
        /// Waits until listener finishes it's work, if it is working.
        /// </summary>
        public void WaitToStop()
        {
            if (_thread == null)
            {
                return;
            }

            try
            {
                _thread.Join();
            }
            catch (Exception ex)
            {
                Logger.Warn(ex.Message, ex);
            }
        }

        #endregion

        #region Private methods

        /// <summary>
        /// Starts listening socket.
        /// </summary>
        private void StartSocket()
        {
            _listenerSocket = new TcpListener(System.Net.IPAddress.Any, Port);
            _listenerSocket.Start();
        }

        /// <summary>
        /// Stops listening socket.
        /// </summary>
        /// <returns>Indicates the result of operation</returns>
        private void StopSocket()
        {
            _listenerSocket.Stop();
        }

        /// <summary>
        /// Entrance point of the thread.
        /// This method is used by the thread to listen incoming requests.
        /// </summary>
        private void DoListenAsThread()
        {
            while (_running)
            {
                try
                {
                    //Wait and get connected socket
                    var clientSocket = _listenerSocket.AcceptSocket();

                    //Raise TCPClientConnected event
                    if (clientSocket.Connected && (TCPClientConnected != null))
                    {
                        TCPClientConnected(this, new TCPClientConnectedEventArgs {ClientSocket = clientSocket});
                    }
                }
                catch (Exception ex)
                {
                    if (!_running)
                    {
                        return;
                    }

                    //on an exception, close connection, wait for a while and start again
                    Logger.Error(ex.Message, ex);

                    try
                    {
                        StopSocket();
                    }
                    catch (Exception exStop)
                    {
                        Logger.Error(exStop.Message, exStop);
                    }

                    Thread.Sleep(3000); //Wait 3 seconds

                    if (!_running)
                    {
                        return;
                    }

                    try
                    {
                        StartSocket();
                    }
                    catch (Exception exStart)
                    {
                        Logger.Error(exStart.Message, exStart);
                    }
                }
            }

            _thread = null;
        }

        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)


Written By
Founder Volosoft
Turkey Turkey
I have started programming at 14 years old using Pascal as hobby. Then I interested in web development (HTML, JavaScript, ASP...) before university.

I graduated from Sakarya University Computer Engineering. At university, I learned C++, Visual Basic.NET, C#, ASP.NET and Java. I partly implemented ARP, IP and TCP protocols in Java as my final term project.

Now, I am working on Windows and web based software development mostly using Microsoft technologies in my own company.

My open source projects:

* ABP Framework: https://abp.io
* jTable: http://jtable.org
* Others: https://github.com/hikalkan

My personal web site:

https://halilibrahimkalkan.com

Comments and Discussions