Пример #1
0
            /// <summary>
            /// Terminates the server as quickly as possible and
            /// removes it from the collection of shared servers.
            /// </summary>
            // ReSharper disable once UnusedMember.Local
            private void TerminateSharedClient()
            {
                EndPoint localEndPoint;
                TcpServer sharedServer;

                lock (s_sharedServers)
                {
                    localEndPoint = GetLocalEndPoint();

                    if (s_sharedServers.TryGetValue(localEndPoint, out sharedServer))
                    {
                        // If the wrapped server and the shared server are the same,
                        // no one has terminated the shared server yet
                        if (m_tcpServer == sharedServer)
                        {
                            // Disconnect and dispose of the old server
                            m_tcpServer.Stop();
                            m_tcpServer.Dispose();

                            // Remove the old server from the
                            // collection of shared servers
                            localEndPoint = GetLocalEndPoint();
                            s_sharedServers.Remove(localEndPoint);
                            s_sharedReferenceCount.Remove(localEndPoint);
                        }
                    }

                    m_tcpServer = null;
                }
            }
Пример #2
0
            /// <summary>
            /// Gets a reference to the shared server listening
            /// on this server's local end point.
            /// </summary>
            /// <returns>A reference to a shared server.</returns>
            private void GetSharedServer()
            {
                const string ConfigurationMismatchError = "Configuration mismatch detected between parsers using shared TCP server: {0}";

                bool sharing;
                EndPoint localEndPoint;
                TcpServer sharedServer;

                lock (s_sharedServers)
                {
                    localEndPoint = GetLocalEndPoint();
                    sharing = s_sharedServers.TryGetValue(localEndPoint, out sharedServer);

                    if (sharing)
                    {
                        // Validate settings to ensure that they match
                        if (sharedServer.ReceiveBufferSize != m_receiveBufferSize)
                            throw new InvalidOperationException(string.Format(ConfigurationMismatchError, "Receive buffer size"));
                    }
                    else
                    {
                        // Create new client and add it to the shared list
                        sharedServer = new TcpServer();
                        s_sharedServers.Add(localEndPoint, sharedServer);
                        s_sharedReferenceCount.Add(localEndPoint, 0);
                    }

                    // Set the TCP server member variable ASAP to guarantee
                    // that it is set before callbacks can be triggered
                    m_tcpServer = sharedServer;

                    // Attach to event handlers
                    sharedServer.ClientConnected += SharedServer_ClientConnected;
                    sharedServer.ClientDisconnected += SharedServer_ClientDisconnected;
                    sharedServer.ClientConnectingException += SharedServer_ClientConnectingException;
                    sharedServer.ReceiveClientData += SharedServer_ReceiveClientData;
                    sharedServer.ReceiveClientDataException += SharedServer_ReceiveClientDataException;
                    sharedServer.SendClientDataException += SharedServer_SendClientDataException;
                    sharedServer.ServerStarted += SharedServer_ServerStarted;
                    sharedServer.ServerStopped += SharedServer_ServerStopped;
                    sharedServer.UnhandledUserException += SharedServer_UnhandledUserException;

                    if (!sharing)
                    {
                        // Initialize settings and connect
                        sharedServer.ConfigurationString = m_configurationString;
                        sharedServer.ReceiveBufferSize = m_receiveBufferSize;
                        sharedServer.Start();
                    }

                    // Increment reference count
                    s_sharedReferenceCount[localEndPoint]++;
                }
            }
Пример #3
0
            /// <summary>
            /// Releases a reference to this server's shared server,
            /// and disposes of the shared server if nobody is using it.
            /// </summary>
            private void ReturnSharedServer()
            {
                EndPoint localEndPoint;

                lock (s_sharedServers)
                {
                    if ((object)m_tcpServer == null)
                        return;

                    // Detach from event handlers
                    m_tcpServer.ClientConnected -= SharedServer_ClientConnected;
                    m_tcpServer.ClientDisconnected -= SharedServer_ClientDisconnected;
                    m_tcpServer.ReceiveClientData -= SharedServer_ReceiveClientData;
                    m_tcpServer.ReceiveClientDataException -= SharedServer_ReceiveClientDataException;
                    m_tcpServer.SendClientDataException -= SharedServer_SendClientDataException;
                    m_tcpServer.ServerStarted -= SharedServer_ServerStarted;
                    m_tcpServer.ServerStopped -= SharedServer_ServerStopped;
                    m_tcpServer.UnhandledUserException -= SharedServer_UnhandledUserException;

                    // Decrement reference count
                    localEndPoint = GetLocalEndPoint();
                    s_sharedReferenceCount[localEndPoint]--;

                    if (s_sharedReferenceCount[localEndPoint] == 0)
                    {
                        // No more references to TCP server
                        // exist so dispose of it
                        m_tcpServer.Stop();
                        m_tcpServer.Dispose();
                        s_sharedServers.Remove(localEndPoint);
                        s_sharedReferenceCount.Remove(localEndPoint);
                    }

                    // Release reference to TCP server
                    m_tcpServer = null;
                }
            }
Пример #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DataListener"/> class.
        /// </summary>
        public DataListener()
        {
            m_id = DefaultID;
            m_server = DefaultServer;
            m_port = DefaultPort;
            m_protocol = DefaultProtocol;
            m_connectToServer = DefaultConnectToServer;
            m_cacheData = DefaultCacheData;
            m_initializeData = DefaultInitializeData;
            m_initializeDataTimeout = DefaultInitializeDataTimeout;
            m_persistSettings = DefaultPersistSettings;
            m_settingsCategory = DefaultSettingsCategory;
            m_data = new List<IDataPoint>();
            m_clientIDs = new ConcurrentDictionary<IClient, Guid>();
            m_initializeWaitHandle = new AutoResetEvent(false);

            m_parser = new PacketParser();
            m_parser.DataParsed += PacketParser_DataParsed;

            m_tcpClient = new TcpClient();
            m_tcpClient.ConnectionAttempt += ClientSocket_ConnectionAttempt;
            m_tcpClient.ConnectionEstablished += ClientSocket_ConnectionEstablished;
            m_tcpClient.ConnectionTerminated += ClientSocket_ConnectionTerminated;
            m_tcpClient.ReceiveDataComplete += ClientSocket_ReceiveDataComplete;
            m_clientIDs.TryAdd(m_tcpClient, Guid.NewGuid());

            m_udpClient = new UdpClient();
            m_udpClient.ConnectionAttempt += ClientSocket_ConnectionAttempt;
            m_udpClient.ConnectionEstablished += ClientSocket_ConnectionEstablished;
            m_udpClient.ConnectionTerminated += ClientSocket_ConnectionTerminated;
            m_udpClient.ReceiveDataComplete += ClientSocket_ReceiveDataComplete;
            m_clientIDs.TryAdd(m_udpClient, Guid.NewGuid());

            m_tcpServer = new TcpServer();
            m_tcpServer.ServerStarted += ServerSocket_ServerStarted;
            m_tcpServer.ServerStopped += ServerSocket_ServerStopped;
            m_tcpServer.ReceiveClientDataComplete += ServerSocket_ReceiveClientDataComplete;

            m_dataInitClient = new TcpClient();
            m_dataInitClient.ConnectionString = "Server={0}:1003; interface=0.0.0.0";
            m_dataInitClient.PayloadAware = true;
            m_dataInitClient.MaxConnectionAttempts = 10;
            m_dataInitClient.ReceiveDataComplete += DataInitClient_ReceiveDataComplete;
        }
Пример #5
0
        private TcpServer InitializeTcpServer()
        {
            TcpServer remotingServer;

            remotingServer = new TcpServer();
            remotingServer.ConfigurationString = "Port=8500";
            remotingServer.IgnoreInvalidCredentials = true;
            remotingServer.PayloadAware = true;
            remotingServer.PersistSettings = true;
            remotingServer.SettingsCategory = "RemotingServer";
            remotingServer.Initialize();

            return remotingServer;
        }
Пример #6
0
        /// <summary>
        /// Create a communications server
        /// </summary>
        /// <remarks>
        /// Note that typical configuration string should be prefixed with a "protocol=tcp" or a "protocol=udp"
        /// </remarks>
        /// <param name="configurationString">The configuration string for the server.</param>
        /// <returns>A communications server.</returns>
        public static IServer Create(string configurationString)
        {
            Dictionary<string, string> configurationSettings = configurationString.ParseKeyValuePairs();
            IServer server;
            string protocol;

            if (configurationSettings.TryGetValue("protocol", out protocol))
            {
                configurationSettings.Remove("protocol");
                StringBuilder settings = new StringBuilder();

                foreach (string key in configurationSettings.Keys)
                {
                    settings.Append(key);
                    settings.Append("=");
                    settings.Append(configurationSettings[key]);
                    settings.Append(";");
                }

                // Create a server instance for the specified protocol.
                switch (protocol.Trim().ToLower())
                {
                    case "tls":
                        server = new TlsServer(settings.ToString());
                        break;
                    case "tcp":
                        server = new TcpServer(settings.ToString());
                        break;
                    case "udp":
                        server = new UdpServer(settings.ToString());
                        break;
                    case "zeromq":
                        server = new ZeroMQServer(settings.ToString());
                        break;
                    default:
                        throw new ArgumentException("Transport protocol \'" + protocol + "\' is not valid");
                }

                // Apply server settings from the connection string to the client.
                foreach (KeyValuePair<string, string> setting in configurationSettings)
                {
                    PropertyInfo property = server.GetType().GetProperty(setting.Key);
                    if (property != null)
                        property.SetValue(server, Convert.ChangeType(setting.Value, property.PropertyType), null);
                }
            }
            else
            {
                throw new ArgumentException("Transport protocol must be specified");
            }

            return server;
        }
Пример #7
0
        /// <summary>
        /// Creates a new <see cref="ClientConnection"/> instance.
        /// </summary>
        /// <param name="parent">Parent data publisher.</param>
        /// <param name="clientID">Client ID of associated connection.</param>
        /// <param name="commandChannel"><see cref="TcpServer"/> command channel used to lookup connection information.</param>
        public ClientConnection(DataPublisher parent, Guid clientID, TcpServer commandChannel)
        {
            m_parent = parent;
            m_clientID = clientID;
            m_commandChannel = commandChannel;
            m_subscriberID = clientID;
            m_keyIVs = null;
            m_cipherIndex = 0;

            // Setup ping timer
            m_pingTimer = new System.Timers.Timer();
            m_pingTimer.Interval = 5000.0D;
            m_pingTimer.AutoReset = true;
            m_pingTimer.Elapsed += m_pingTimer_Elapsed;
            m_pingTimer.Start();

            // Setup reconnect timer
            m_reconnectTimer = new System.Timers.Timer();
            m_reconnectTimer.Interval = 1000.0D;
            m_reconnectTimer.AutoReset = false;
            m_reconnectTimer.Elapsed += m_reconnectTimer_Elapsed;

            // Attempt to lookup remote connection identification for logging purposes
            try
            {
                TransportProvider<Socket> client;
                IPEndPoint remoteEndPoint = null;

                if ((object)commandChannel != null && commandChannel.TryGetClient(clientID, out client))
                    remoteEndPoint = client.Provider.RemoteEndPoint as IPEndPoint;

                if ((object)remoteEndPoint != null)
                {
                    m_ipAddress = remoteEndPoint.Address;

                    if (remoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6)
                        m_connectionID = "[" + m_ipAddress + "]:" + remoteEndPoint.Port;
                    else
                        m_connectionID = m_ipAddress + ":" + remoteEndPoint.Port;

                    try
                    {
                        IPHostEntry ipHost = Dns.GetHostEntry(remoteEndPoint.Address);

                        if (!ipHost.HostName.IsNullOrWhiteSpace())
                        {
                            m_hostName = ipHost.HostName;
                            m_connectionID = m_hostName + " (" + m_connectionID + ")";
                        }
                    }
                    catch
                    {
                        // Just ignoring possible DNS lookup failures...
                    }
                }
            }
            catch
            {
                // At worst we'll just use the client GUID for identification
                m_connectionID = (m_subscriberID == Guid.Empty ? clientID.ToString() : m_subscriberID.ToString());
            }

            if (m_connectionID.IsNullOrWhiteSpace())
                m_connectionID = "unavailable";

            if (m_hostName.IsNullOrWhiteSpace())
            {
                if (m_ipAddress != null)
                    m_hostName = m_ipAddress.ToString();
                else
                    m_hostName = m_connectionID;
            }

            if (m_ipAddress == null)
                m_ipAddress = System.Net.IPAddress.None;
        }
Пример #8
0
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="ClientConnection"/> object and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!m_disposed)
            {
                try
                {
                    if (disposing)
                    {
                        if (m_pingTimer != null)
                        {
                            m_pingTimer.Elapsed -= m_pingTimer_Elapsed;
                            m_pingTimer.Dispose();
                        }
                        m_pingTimer = null;

                        if (m_reconnectTimer != null)
                        {
                            m_reconnectTimer.Elapsed -= m_reconnectTimer_Elapsed;
                            m_reconnectTimer.Dispose();
                        }
                        m_reconnectTimer = null;

                        DataChannel = null;
                        m_commandChannel = null;
                        m_ipAddress = null;
                        m_subscription = null;
                        m_parent = null;
                    }
                }
                finally
                {
                    m_disposed = true;  // Prevent duplicate dispose.
                }
            }
        }