Ejemplo n.º 1
0
            public AsyncSocket Connect(GlobalClient client)
            {
                lock (this)
                {
                    // 这个能放到(lock(this)外吗?严格点,放这里更安全。
                    // TODO IsCompletedSuccessfully net471之类的没有这个方法,先不管。net471之类的unity要用。
                    if (null != Logined && Logined.Task.IsCompletedSuccessfully)
                    {
                        return(Logined.Task.Result);
                    }

                    if (global::Zeze.Util.Time.NowUnixMillis - LastErrorTime < ForbitPeriod)
                    {
                        throw new AbortException("GloalAgent.Connect: In Forbit Login Period");
                    }

                    if (null == Socket)
                    {
                        Socket = client.NewClientSocket(Host, Port, this);
                        // 每次新建连接创建future,没并发问题吧,还没仔细考虑。
                        Logined = new TaskCompletionSource <AsyncSocket>();
                    }
                }
                // 重新设置一个总超时。整个登录流程有ConnectTimeout,LoginTimeout。
                // 要注意,这个超时发生时,登录流程可能还在进行中。
                // 这里先不清理,下一次进来再次等待(需要确认这样可行)。
                if (false == Logined.Task.Wait(5000))
                {
                    lock (this)
                    {
                        // 并发的等待,简单用个规则:在间隔期内不再设置。
                        long now = global::Zeze.Util.Time.NowUnixMillis;
                        if (now - LastErrorTime > ForbitPeriod)
                        {
                            LastErrorTime = now;
                        }
                    }
                    throw new AbortException("GloalAgent.Connect: Login Timeout");
                }
                return(Socket);
            }
Ejemplo n.º 2
0
 public void OnSocketClose(GlobalClient client, Exception ex)
 {
     lock (this)
     {
         if (null == Socket)
         {
             // active close
             return;
         }
         Socket = null;
     }
     if (Logined.Task.IsCompletedSuccessfully)
     {
         foreach (var database in client.Zeze.Databases.Values)
         {
             foreach (var table in database.Tables)
             {
                 table.ReduceInvalidAllLocalOnly(GlobalCacheManagerHashIndex);
             }
         }
         client.Zeze.CheckpointRun();
     }
     Logined.TrySetException(ex); // 连接关闭,这个继续保持。仅在Connect里面需要时创建。
 }
Ejemplo n.º 3
0
        public void Start(string hostNameOrAddress, int port)
        {
            lock (this)
            {
                if (null != Client)
                {
                    return;
                }

                Client = new GlobalClient(this, Zeze);
                // Zeze-App 自动启用持久化的全局唯一的Rpc.SessionId生成器。
                Client.SessionIdGenerator = Zeze.TableSys.AutoKeys.GetAutoKey(Client.Name).Next;

                Client.AddFactoryHandle(new GlobalCacheManager.Reduce().TypeId, new Service.ProtocolFactoryHandle()
                {
                    Factory     = () => new GlobalCacheManager.Reduce(),
                    Handle      = ProcessReduceRequest,
                    NoProcedure = true
                });
                Client.AddFactoryHandle(new GlobalCacheManager.Acquire().TypeId, new Service.ProtocolFactoryHandle()
                {
                    Factory     = () => new GlobalCacheManager.Acquire(),
                    NoProcedure = true
                                  // 同步方式调用,不需要设置Handle: Response Timeout
                });
                Client.AddFactoryHandle(new GlobalCacheManager.Login().TypeId, new Service.ProtocolFactoryHandle()
                {
                    Factory     = () => new GlobalCacheManager.Login(),
                    NoProcedure = true
                });
                Client.AddFactoryHandle(new GlobalCacheManager.ReLogin().TypeId, new Service.ProtocolFactoryHandle()
                {
                    Factory     = () => new GlobalCacheManager.ReLogin(),
                    NoProcedure = true
                });
                Client.AddFactoryHandle(new GlobalCacheManager.NormalClose().TypeId, new Service.ProtocolFactoryHandle()
                {
                    Factory     = () => new GlobalCacheManager.NormalClose(),
                    NoProcedure = true
                });

                var globals = hostNameOrAddress.Split(';');
                Agents = new Agent[globals.Length];
                for (int i = 0; i < globals.Length; ++i)
                {
                    var hp = globals[i].Split(':');
                    if (hp.Length > 1)
                    {
                        Agents[i] = new Agent(hp[0], int.Parse(hp[1]), i);
                    }
                    else
                    {
                        Agents[i] = new Agent(hp[0], port, i);
                    }
                }
                foreach (var agent in Agents)
                {
                    try
                    {
                        agent.Connect(Client);
                    }
                    catch (Exception ex)
                    {
                        // 允许部分GlobalCacheManager连接错误时,继续启动程序,虽然后续相关事务都会失败。
                        logger.Error(ex, "GlobalAgent.Connect");
                    }
                }
            }
        }