/// <summary> /// Initializes a new instance of the <see cref="DataListener"/> class. /// </summary> public DataListener() : base() { m_id = DefaultID; m_server = DefaultServer; m_port = DefaultPort; m_protocol = DefaultProtocol; m_connectToServer = DefaultConnectToServer; m_initializeData = DefaultInitializeData; m_initializeDataTimeout = DefaultInitializeDataTimeout; m_persistSettings = DefaultPersistSettings; m_settingsCategory = DefaultSettingsCategory; m_data = new List<IDataPoint>(); 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_udpClient = new UdpClient(); m_udpClient.ConnectionAttempt += ClientSocket_ConnectionAttempt; m_udpClient.ConnectionEstablished += ClientSocket_ConnectionEstablished; m_udpClient.ConnectionTerminated += ClientSocket_ConnectionTerminated; m_udpClient.ReceiveDataComplete += ClientSocket_ReceiveDataComplete; 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"; m_dataInitClient.PayloadAware = true; m_dataInitClient.MaxConnectionAttempts = 10; m_dataInitClient.ReceiveDataComplete += DataInitClient_ReceiveDataComplete; }
/// <summary> /// Create a communications server /// </summary> /// <remarks> /// Note that typical configuration string should be prefixed with a "protocol=tcp" or a "protocol=udp" /// </remarks> public static IServer CreateCommunicationServer(string configurationString) { Dictionary<string, string> configurationData = configurationString.ParseKeyValuePairs(); IServer server = null; string protocol; if (configurationData.TryGetValue("protocol", out protocol)) { configurationData.Remove("protocol"); StringBuilder settings = new StringBuilder(); foreach (string key in configurationData.Keys) { settings.Append(key); settings.Append("="); settings.Append(configurationData[key]); settings.Append(";"); } switch (protocol.ToLower()) { case "tcp": server = new TcpServer(settings.ToString()); break; case "udp": server = new UdpServer(settings.ToString()); break; default: throw new ArgumentException("Transport protocol \'" + protocol + "\' is not valid."); } } else { throw new ArgumentException("Transport protocol must be specified."); } return server; }
/// <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. } } }
/// <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 (!string.IsNullOrWhiteSpace(ipHost.HostName)) { 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 (string.IsNullOrWhiteSpace(m_connectionID)) m_connectionID = "unavailable"; if (string.IsNullOrWhiteSpace(m_hostName)) { if (m_ipAddress != null) m_hostName = m_ipAddress.ToString(); else m_hostName = m_connectionID; } if (m_ipAddress == null) m_ipAddress = System.Net.IPAddress.None; }
/// <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 = null; 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 "tcp": server = new TcpServer(settings.ToString()); break; case "udp": server = new UdpServer(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; }