Exemplo n.º 1
0
        /// <summary>
        /// Starts distributed session on each server and returns DistributedClient of TInterface
        /// to provide access to TInterface on the distributed nodes.
        /// </summary>
        /// <typeparam name="TInterface">The interface type to be hosted on the distributed nodes.</typeparam>
        /// <param name="implementationType">The concrete type that each distributed node will host.</param>
        /// <param name="subscriptionRate">Produces N client proxy instances per logical processor on each distributed node (min of 0.0 which produces 1 proxy, max of 30 which produces 30 proxies per logical processor).</param>
        /// <param name="logPollingInterval">The polling interval for client to sweep logs from the distributed node. Value of 0 will prevent logs from being polled.</param>
        /// <param name="logLevel">Limit logging to this level or lower. Error = 0, Warning = 1, Info = 2, Debug = 3</param>
        /// <param name="servers">The IPEndPoint for each distritued node host to be used by the client.</param>
        /// <returns></returns>
        public static DistributedClient <TInterface> Connect <TInterface>(Type implementationType,
                                                                          float subscriptionRate,
                                                                          int logPollingInterval,
                                                                          LogLevel logLevel,
                                                                          params IPEndPoint[] servers) where TInterface : class
        {
            if (null == servers || servers.Length == 0)
            {
                throw new ArgumentNullException("servers");
            }

            if (null == implementationType)
            {
                throw new ArgumentNullException("implementationType");
            }

            var interfaceType = typeof(TInterface);

            if (!interfaceType.IsInterface)
            {
                throw new ArgumentException("TInterface not interface");
            }

            if (subscriptionRate < 0.0f)
            {
                subscriptionRate = 0.0f;                          //one per node, where 1.0 would be one per logical processor
            }
            if (subscriptionRate > 30.0f)
            {
                subscriptionRate = 30.0f;                           //prevent crazy over subscription
            }
            if (logPollingInterval < 0)
            {
                logPollingInterval = 0;
            }
            if (logPollingInterval > 300)
            {
                logPollingInterval = 300;                           //max of 5 minutes
            }
            //get singleton package with hash
            var packager = Packager.Create();
            var request  = new DistributedSessionRequest()
            {
                PackageName            = packager.Hash.Name,
                ContractTypeName       = interfaceType.ToConfigName(),
                ImplementationTypeName = implementationType.ToConfigName(),
                HoursToLive            = 48,
                LogLevel = logLevel
            };

            var nodes       = new ConcurrentDictionary <IPEndPoint, DistributedSessionNode>();
            var failedNodes = new ConcurrentDictionary <IPEndPoint, Exception>();

            Parallel.ForEach(servers, server =>
            {
                try
                {
                    using (var client = new ServiceClient(server))
                    {
                        if (!client.HasPackage(packager.Hash))
                        {
                            client.AddUpdatePackage(packager.Hash, packager.Package());
                        }
                        var node = client.CreateSession(request);
                        // when a node is hosted using IPAddress.Any or is behind a NAT,
                        // the node endpoint will be unusable by the node,
                        // so set it using the client's server endpoint
                        if (!node.EndPoint.Equals(server))
                        {
                            node.EndPoint = server;
                        }
                        nodes.TryAdd(server, node);
                    }
                }
                catch (Exception ex)
                {
                    failedNodes.TryAdd(server, ex);
                }
            });

            var result = new DistributedClient <TInterface>(servers,
                                                            nodes.Values.ToArray(),
                                                            failedNodes.Keys.ToArray(),
                                                            failedNodes.Values.ToArray(),
                                                            subscriptionRate,
                                                            logPollingInterval);

            return(result);
        }
 public DistributedSessionNode CreateSession(DistributedSessionRequest request)
 {
     return(Proxy.CreateSession(request));
 }