/// <summary> /// The constructor. /// </summary> /// <param name="binding">The binding.</param> /// <param name="endpointAddress">The endpoint address.</param> /// <param name="hostReconnectIntervalMilliseconds">The cache host reconnect interval, in milliseconds.</param> public CommunicationClient(Binding binding, EndpointAddress endpointAddress, int hostReconnectIntervalMilliseconds) { // Sanitize if (binding == null) { throw new ArgumentNullException("binding"); } if (endpointAddress == null) { throw new ArgumentNullException("endpointAddress"); } if (hostReconnectIntervalMilliseconds <= 0) { throw new ArgumentException("must be greater than 0", "hostReconnectIntervalMilliseconds"); } // Initialize the channel factory with the binding and endpoint address _channelFactory = new ChannelFactory<IClientToCacheContract>(binding, endpointAddress); // Set the cache host reconnect interval _hostReconnectIntervalMilliseconds = hostReconnectIntervalMilliseconds; // Initialize WCF _proxy = _channelFactory.CreateChannel(); _proxyComm = _proxy as ICommunicationObject; // Set connected before opening to avoid a race _isConnected = true; // Initialize and configure the reconnect timer to never fire _reconnectTimer = new Timer(ReconnectToServer, null, Timeout.Infinite, Timeout.Infinite); }
/// <summary> /// Connects or reconnects to the server. /// </summary> /// <param name="state">The state. Ignored but required for timer callback methods. Pass null.</param> private void ReconnectToServer(object state) { // Check if already reconnected - ahead of the lock for speed if (_isConnected) { // Do nothing return; } // Lock to ensure atomic operations lock (_reconnectLock) { // Double check if already reconnected if (_isConnected) { // Do nothing return; } // Close and abort the Proxy Communication if needed try { // Attempt the close _proxyComm.Close(); } catch { // Close failed, abort it _proxyComm.Abort(); } // Re-initialize the Proxy _proxy = _channelFactory.CreateChannel(); _proxyComm = _proxy as ICommunicationObject; // Attempt the actual reconnection try { _proxyComm.Open(); } catch { // Reconnection failed, so we're done (the Timer will retry) return; } // If we got here, we're back online, adjust reconnected status _isConnected = true; // Disable the reconnect timer to stop trying to reconnect _reconnectTimer.Change(Timeout.Infinite, Timeout.Infinite); // Fire the reconnected event var reconnected = Reconnected; if (reconnected != null) { reconnected(this, EventArgs.Empty); } } }