/// <summary> /// The current networking code should register and unregister when it starts and disposes. /// The intent is that this will allow UI elements to pick up global network state /// from a corresponding property aggregated and published here in NetworkModel. We normally should have only one /// PropertyPublisher registered at a time, but we will keep track of multiple, and /// report an indeterminate state if more than one is registered. /// </summary> /// <param name="publisher">A PropertyPublisher with a NetworkStatus property</param> /// <param name="register">true to register, false to unregister</param> public void RegisterNetworkStatusProvider(PropertyPublisher publisher, bool register, NetworkStatus initialStatus) { using (Synchronizer.Lock(this.m_NetworkStatusProviders)) { if (register) { if (m_NetworkStatusProviders.ContainsKey(publisher)) { throw (new ArgumentException("A Network Status Provider can only be registered once.")); } publisher.Changed["NetworkStatus"].Add(new PropertyEventHandler(OnNetworkStatusChanged)); NetworkStatus newStatus = initialStatus.Clone(); m_NetworkStatusProviders.Add(publisher, newStatus); if (m_NetworkStatusProviders.Count > 1) { //Multiple providers --> unknown global status newStatus = new NetworkStatus(); } if (m_NetworkStatus.StatusChanged(newStatus)) { using (Synchronizer.Lock(this.SyncRoot)) { this.SetPublishedProperty("NetworkStatus", ref m_NetworkStatus, newStatus); } } } else { if (!m_NetworkStatusProviders.ContainsKey(publisher)) { throw (new ArgumentException("A Network Status Provider can't be unregistered until it has been registered.")); } m_NetworkStatusProviders.Remove(publisher); publisher.Changed["NetworkStatus"].Remove(new PropertyEventHandler(OnNetworkStatusChanged)); if (m_NetworkStatusProviders.Count == 1) { foreach (NetworkStatus ns in m_NetworkStatusProviders.Values) { if (m_NetworkStatus.StatusChanged(ns)) { using (Synchronizer.Lock(this.SyncRoot)) { this.SetPublishedProperty("NetworkStatus", ref m_NetworkStatus, ns); } } break; } } if (m_NetworkStatusProviders.Count == 0) { if (m_NetworkStatus.StatusChanged(NetworkStatus.DisconnectedNetworkStatus)) { using (Synchronizer.Lock(this.SyncRoot)) { this.SetPublishedProperty("NetworkStatus", ref m_NetworkStatus, NetworkStatus.DisconnectedNetworkStatus); } } } } } }
/// <summary> /// Start the client: attempt to connect. Maintain the connection and receive inbound messages. /// </summary> public void Start() { using (Synchronizer.Lock(this.SyncRoot)) { NetworkStatus newStatus = m_NetworkStatus.Clone(); newStatus.ConnectionStatus = ConnectionStatus.TryingToConnect; this.SetPublishedProperty("NetworkStatus", ref m_NetworkStatus, newStatus); } //A thread to establish and maintain the connection to the server m_ConnectThread = new Thread(new ThreadStart(ConnectThread)); m_ConnectThread.Start(); //A thread to receive inbound messages. m_ReceiveThread = new Thread(new ThreadStart(ReceiveThread)); m_ReceiveThread.Start(); //A thread for diagnostics m_UtilityThread = new Thread(new ThreadStart(UtilityThread)); m_UtilityThread.Start(); }