/// <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); }
public ServerStatusEnumerator(ServerPool owner) { this._owner = owner; }