Пример #1
0
 public void UnBind(Zeze.Net.AsyncSocket link, IEnumerable <int> moduleIds, Zeze.Net.AsyncSocket provider, bool isOnProviderClose = false)
 {
     lock (this)
     {
         foreach (var moduleId in moduleIds)
         {
             if (Binds.TryGetValue(moduleId, out var exist))
             {
                 if (exist == provider.SessionId) // check owner? 也许不做这个检测更好?
                 {
                     Binds.Remove(moduleId);
                     if (false == isOnProviderClose)
                     {
                         (provider.UserState as ProviderSession)?.RemoveLinkSession(moduleId, link.SessionId);
                     }
                 }
                 else
                 {
                     var oldSocket = App.Instance.ProviderService.GetSocket(exist);
                     logger.Warn("LinkSession.UnBind not owner {0} {1} {2}", moduleId,
                                 oldSocket.Socket.RemoteEndPoint, provider.Socket.RemoteEndPoint);
                 }
             }
         }
     }
 }
Пример #2
0
        public override void OnSocketClose(Zeze.Net.AsyncSocket so, System.Exception e)
        {
            base.OnSocketClose(so, e);
            var linkSession = so.UserState as LinkSession;

            linkSession?.OnClose();
        }
Пример #3
0
 public void UnBind(Zeze.Net.AsyncSocket link, int moduleId, Zeze.Net.AsyncSocket provider, bool isOnProviderClose = false)
 {
     UnBind(link, new HashSet <int>()
     {
         moduleId
     }, provider, isOnProviderClose);
 }
Пример #4
0
        public void OnProviderClose(Zeze.Net.AsyncSocket provider)
        {
            ProviderSession providerSession = provider.UserState as ProviderSession;

            if (null == providerSession)
            {
                return;
            }

            // unbind module
            UnBindModules(provider, providerSession.StaticBinds.Keys, true);
            providerSession.StaticBinds.Clear();

            // unbind LinkSession
            lock (providerSession.LinkSessionIds)
            {
                foreach (var e in providerSession.LinkSessionIds)
                {
                    foreach (var linkSid in e.Value)
                    {
                        var link = App.Instance.LinkdService.GetSocket(linkSid);
                        if (null != link)
                        {
                            var linkSession = link.UserState as LinkSession;
                            linkSession?.UnBind(link, e.Key, provider, true);
                        }
                    }
                }
                providerSession.LinkSessionIds.Clear();
            }
        }
Пример #5
0
        private void SendKick(Zeze.Net.AsyncSocket sender, long linkSid, int code, string desc)
        {
            var p = new Kick();

            p.Argument.Linksid = linkSid;
            p.Argument.Code    = code;
            p.Argument.Desc    = desc;
            p.Send(sender);
        }
Пример #6
0
        public override void OnHandshakeDone(Zeze.Net.AsyncSocket sender)
        {
            base.OnHandshakeDone(sender);
            sender.UserState = new ProviderSession(sender.SessionId);

            var announce = new Provider.AnnounceLinkInfo();

            announce.Argument.LinkId            = 0; // reserve
            announce.Argument.ProviderSessionId = sender.SessionId;
            sender.Send(announce);
        }
Пример #7
0
 public override void OnSocketProcessInputBuffer(Zeze.Net.AsyncSocket so, Zeze.Serialize.ByteBuffer input)
 {
     if (so.IsHandshakeDone)
     {
         AppendInputBuffer(so.SessionId, input);
         input.ReadIndex = input.WriteIndex;
     }
     else
     {
         base.OnSocketProcessInputBuffer(so, input);
     }
 }
Пример #8
0
        public override void DispatchUnknownProtocol(Zeze.Net.AsyncSocket so, int type, Zeze.Serialize.ByteBuffer data)
        {
            var linkSession = so.UserState as LinkSession;

            if (null == linkSession || null == linkSession.UserId)
            {
                ReportError(so.SessionId, Linkd.BReportError.FromLink, Linkd.BReportError.CodeNotAuthed, "not authed.");
                return;
            }

            var moduleId = global::Zeze.Net.Protocol.GetModuleId(type);
            var dispatch = new Provider.Dispatch();

            dispatch.Argument.LinkSid      = so.SessionId;
            dispatch.Argument.UserId       = linkSession.UserId;
            dispatch.Argument.ProtocolType = type;
            dispatch.Argument.ProtocolData = new Zeze.Net.Binary(data);
            dispatch.Argument.States.AddRange(linkSession.UserStates);
            dispatch.Argument.Statex = linkSession.UserStatex;

            long provider;

            if (linkSession.TryGetProvider(moduleId, out provider))
            {
                var socket = App.Instance.ProviderService.GetSocket(provider);
                if (null != socket)
                {
                    socket.Send(dispatch);
                    return;
                }
                // 原来绑定的provider找不到连接,尝试继续从静态绑定里面查找。
                // 此时应该处于 UnBind 过程中。
                //linkSession.UnBind(so, moduleId, null);
            }

            if (App.Instance.gnet_Provider.ChoiceProviderAndBind(moduleId, so, out provider))
            {
                var providerSocket = App.Instance.ProviderService.GetSocket(provider);
                if (null != providerSocket)
                {
                    // ChoiceProviderAndBind 内部已经处理了绑定。这里只需要发送。
                    providerSocket.Send(dispatch);
                    return;
                }
                // 找到provider但是发送之前连接关闭,当作没有找到处理。这个窗口很小,再次查找意义不大。
            }
            ReportError(so.SessionId, Linkd.BReportError.FromLink, Linkd.BReportError.CodeNoProvider, "no provider.");
        }
Пример #9
0
 public void Bind(Zeze.Net.AsyncSocket link, IEnumerable <int> moduleIds, Zeze.Net.AsyncSocket provider)
 {
     lock (this)
     {
         foreach (var moduleId in moduleIds)
         {
             if (Binds.TryGetValue(moduleId, out var exist))
             {
                 var oldSocket = App.Instance.ProviderService.GetSocket(exist);
                 logger.Warn("LinkSession.Bind replace provider {0} {1} {2}", moduleId,
                             oldSocket.Socket.RemoteEndPoint, provider.Socket.RemoteEndPoint);
             }
             Binds[moduleId] = provider.SessionId;
             (provider.UserState as ProviderSession).AddLinkSession(moduleId, link.SessionId);
         }
     }
 }
Пример #10
0
        private void SendResultIfSizeExceed(Zeze.Net.AsyncSocket sender, ModuleRedirectAllResult result)
        {
            int size = 0;

            foreach (var hashResult in result.Argument.Hashs.Values)
            {
                size += hashResult.Params.Count;
                foreach (var hashActions in hashResult.Actions)
                {
                    size += hashActions.Params.Count;
                }
            }
            if (size > 2 * 1024 * 1024) // 2M
            {
                result.Send(sender);
                result.Argument.Hashs.Clear();
            }
        }
Пример #11
0
        public bool ChoiceProviderAndBind(int moduleId, Zeze.Net.AsyncSocket link, out long provider)
        {
            var serviceName = MakeServiceName(GameServerServiceNamePrefix, moduleId);
            var linkSession = link.UserState as LinkSession;

            provider = 0;
            if (false == App.Instance.ServiceManagerAgent.SubscribeStates.TryGetValue(
                    serviceName, out var volatileProviders))
            {
                return(false);
            }

            // 这里保存的 ProviderModuleState 是该moduleId的第一个bind请求去订阅时记录下来的,
            // 这里仅使用里面的ChoiceType和ConfigType。这两个参数对于相同的moduleId都是一样的。
            // 如果需要某个provider.SessionId,需要查询 ServiceInfoListSortedByIdentity 里的ServiceInfo.LocalState。
            var providerModuleState = volatileProviders.SubscribeInfo.LocalState as ProviderModuleState;

            switch (providerModuleState.ChoiceType)
            {
            case BModule.ChoiceTypeHashUserId:
                return(ChoiceHash(volatileProviders, Zeze.Serialize.ByteBuffer.calc_hashnr(linkSession.UserId), out provider));

            case BModule.ChoiceTypeHashRoleId:
                if (linkSession.UserStates.Count > 0)
                {
                    return(ChoiceHash(volatileProviders, Zeze.Serialize.ByteBuffer.calc_hashnr(linkSession.UserStates[0]), out provider));
                }
                else
                {
                    return(false);
                }
            }
            if (ChoiceLoad(volatileProviders, out provider))
            {
                // 这里不判断null,如果失败让这次选择失败,否则选中了,又没有Bind以后更不好处理。
                var providerSocket  = gnet.App.Instance.ProviderService.GetSocket(provider);
                var providerSession = providerSocket.UserState as ProviderSession;
                linkSession.Bind(link, providerSession.StaticBinds.Keys, providerSocket);
                return(true);
            }

            return(false);
        }
Пример #12
0
        private void UnBindModules(Zeze.Net.AsyncSocket provider, IEnumerable <int> modules, bool isOnProviderClose = false)
        {
            var providerSession = provider.UserState as ProviderSession;

            foreach (var moduleId in modules)
            {
                if (false == isOnProviderClose)
                {
                    providerSession.StaticBinds.TryRemove(moduleId, out var _);
                }
                var serviceName = MakeServiceName(providerSession.Info.ServiceNamePrefix, moduleId);
                if (false == App.Instance.ServiceManagerAgent.SubscribeStates.TryGetValue(
                        serviceName, out var volatileProviders))
                {
                    continue;
                }
                // UnBind 不删除provider-list,这个总是通过ServiceManager通告更新。
                // 这里仅仅设置该moduleId对应的服务的状态不可用。
                volatileProviders.SetServiceIdentityReadyState(providerSession.Info.ServiceIndentity, null);
            }
        }
Пример #13
0
 public override void OnHandshakeDone(Zeze.Net.AsyncSocket sender)
 {
     sender.IsHandshakeDone = true;
     SetHandshakeDone(sender.SessionId);
 }
Пример #14
0
 public override void OnSocketClose(Zeze.Net.AsyncSocket so, Exception e)
 {
     SetSocketClose(so.SessionId);
     base.OnSocketClose(so, e);
 }
Пример #15
0
 public override void OnSocketClose(Zeze.Net.AsyncSocket so, System.Exception e)
 {
     // 先unbind。这样避免有时间窗口。
     gnet.App.Instance.gnet_Provider.OnProviderClose(so);
     base.OnSocketClose(so, e);
 }
Пример #16
0
 public override void OnHandshakeDone(Zeze.Net.AsyncSocket sender)
 {
     base.OnHandshakeDone(sender);
     sender.UserState = new LinkSession(sender.SessionId);
 }