예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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);
                }
            }
        }