Click here to Skip to main content
15,896,063 members
Articles / Programming Languages / C#

A Flexible Plugin System

Rate me:
Please Sign up or sign in to vote.
4.98/5 (25 votes)
3 Sep 2008LGPL34 min read 131.7K   1.8K   163  
A generic plugin system used to load and manage plugins
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;

namespace Fadd.Commands.Net
{
    /// <summary>
    /// Receives commands from the client and invoked them in the server dispatcher.
    /// </summary>
    public class CommandServer
    {
        private TcpListener _listener;
        private readonly List<CommandChannel> _clients = new List<CommandChannel>();
        private readonly CommandManager _cmdMgr;

        /// <summary>
        /// Initializes a new instance of the <see cref="CommandServer"/> class.
        /// </summary>
        /// <param name="mgr">Manager that the incoming commands are invoked in.</param>
        public CommandServer(CommandManager mgr)
        {
            Check.Require(mgr, "mgr");
            _cmdMgr = mgr;
        }

        /// <summary>
        /// Starts the server.
        /// </summary>
        /// <param name="address">IP address that we accept incoming connections on.</param>
        /// <param name="port">Port that the server accepts new connections on.</param>
        public void Start(IPAddress address, int port)
        {
            if (_listener != null)
                throw new InvalidOperationException("CommandServer is already started.");

            _listener = new TcpListener(address, port);
            _listener.Start(10);
            _listener.BeginAcceptSocket(OnAcceptSocket, null);
        }

        /// <summary>
        /// Stops the server.
        /// </summary>
        public void Stop()
        {
            lock (_clients)
            {
                foreach (CommandChannel client in _clients)
                    client.Dispose();
                _clients.Clear();                
            }

            _listener.Stop();
        }

        private void OnAcceptSocket(IAsyncResult ar)
        {
            Socket socket;
            try
            {
                socket = _listener.EndAcceptSocket(ar);
                _listener.BeginAcceptSocket(OnAcceptSocket, null);
            }
            catch (SocketException)
            {
                return;
            }
            catch(ObjectDisposedException)
            {
                return;
            }

            CommandChannel tunnel = new CommandChannel(_cmdMgr, socket);
            tunnel.Disconnected += OnClientDisconnected;
            tunnel.AutoReconnect = false;
            lock (_clients)
                _clients.Add(tunnel);
        }

        private void OnClientDisconnected(object source, DisconnectedEventArgs args)
        {
            lock (_clients)
            {
                CommandChannel tunnel = (CommandChannel) source;
                tunnel.Disconnected -= OnClientDisconnected;
                _clients.Remove(tunnel);
            }
        }
    }
}

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 1TCompany AB
Sweden Sweden

Comments and Discussions