Esempio n. 1
0
        /// <summary>
        /// Creates an instance of <see cref="ServerPool"/>
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        internal static ServerPool Create(
            ClientOptions options
            )
        {
            //collects the defined server endpoints
            List <ServerEndPoint> definedEndPoints = options.Servers
                                                     .Distinct()
                                                     .ToList();

            if (definedEndPoints.Count == 0)
            {
                //none was defined, so adds the default one
                definedEndPoints.Add(ServerEndPoint.Default());
            }
            else if (options.NoRandomize == false)
            {
                //gives a shuffle to the list
                Shuffle(definedEndPoints);
            }

            //creates the main instance with the effective collection
            var instance = new ServerPool(options);

            foreach (ServerEndPoint ep in definedEndPoints)
            {
                instance._servers.AddLast(
                    new ServerConnectionStatus(ep, isImplicit: false)
                    );
            }
            return(instance);
        }
        /// <summary>
        /// Processes the very first INFO message issued by the server
        /// </summary>
        /// <param name="segment"></param>
        /// <param name="notifyOnServerAddition"></param>
        /// <returns></returns>
        private ServerInfo ProcessInfo(
            ArraySegment <byte> segment,
            bool notifyOnServerAddition
            )
        {
            ServerInfo info = null;

            if (segment.Count > 0)
            {
                info = ServerInfo.Create(segment);

                //converts the URLs array received from the server to a new endpoint
                bool currentIsSecured = this._srvPool.CurrentServer.EndPoint.Secured;
                List <ServerEndPoint> newEndPoints = (info.ConnectUrls ?? new string[0])
                                                     .Select(_ => ServerEndPoint.ParseAnonymous(_, currentIsSecured))
                                                     .Where(_ => _ != null)
                                                     .ToList();

                if (newEndPoints.Count != 0)
                {
                    if (this._options.NoRandomize == false)
                    {
                        // If randomization is allowed, shuffle the received array,
                        // not the entire pool. We want to preserve the pool's
                        // order up to this point (this would otherwise be
                        // problematic for the (re)connect loop).
                        ServerPool.Shuffle(newEndPoints);
                    }

                    bool serverAdded = this._srvPool.AddAsImplicit(newEndPoints);
                    if (notifyOnServerAddition &&
                        serverAdded
                        )
                    {
                        //notify host
                        this._options.ServerDiscoveredEventHandler?.Invoke(new ServerDiscoveredEventArgs()
                        {
                            Connection = this._owner,
                            State      = this._status
                        });
                    }
                }
            }
            return(info);
        }
        private const int ReadTimeout = 5000;   //ms


        /// <summary>
        /// Creates an instance of <see cref="ConnectionManager"/>
        /// </summary>
        /// <param name="owner"></param>
        internal ConnectionManager(Connection owner)
        {
            this._owner   = owner;
            this._options = owner.OptionsInternal;

            //create the server pool manager
            this._srvPool = ServerPool.Create(this._options);
            this._srvPool.IncrementStatsCounter = () =>
            {
                Interlocked.Increment(ref this._statsReconnections);
            };

            //create the incoming data parser
            this._parser = new Parser()
            {
                NotifyOperation = this.NotifyOperationHandler,
                NotifyMessage   = this.NotifyMessageHandler,
                NotifyError     = this.NotifyErrorHandler
            };

            //prepare a single instance of args to pass when the StateChanged event is raised:
            //that's for performance reasons
            this._stateChangedEventArgs = new StateChangedEventArgs(this._owner);
        }
Esempio n. 4
0
 public ServerStatusEnumerator(ServerPool owner)
 {
     this._owner = owner;
 }