示例#1
0
文件: Rpc.cs 项目: e2wugui/zeze
        internal override void Dispatch(Service service, Service.ProtocolFactoryHandle factoryHandle)
        {
            if (IsRequest)
            {
                service.DispatchProtocol(this, factoryHandle);
                return;
            }

            // response, 从上下文中查找原来发送的rpc对象,并派发该对象。
            Rpc <TArgument, TResult> context = service.RemoveRpcContext <Rpc <TArgument, TResult> >(SessionId);

            if (null == context)
            {
                logger.Info("rpc response: lost context, maybe timeout. {0}", this);
                return;
            }

            context.IsRequest  = false;
            context.Result     = Result;
            context.Sender     = Sender;
            context.ResultCode = ResultCode;
            context.UserState  = UserState;

            if (context.Future != null)
            {
                context.Future.SetResult(context.Result);
                return;                // SendForWait,设置结果唤醒等待者。
            }
            context.IsTimeout = false; // not need
            if (null != context.ResponseHandle)
            {
                service.DispatchRpcResponse(context, context.ResponseHandle, factoryHandle);
            }
        }
示例#2
0
 internal virtual void Dispatch(Service service, Service.ProtocolFactoryHandle factoryHandle)
 {
     service.DispatchProtocol(this, factoryHandle);
 }
示例#3
0
        /// <summary>
        /// Id + size + protocol.bytes
        /// </summary>
        /// <param name="bb"></param>
        /// <returns></returns>
        internal static void Decode(Service service, AsyncSocket so, ByteBuffer bb, Zeze.Services.ToLuaService.ToLua toLua = null)
        {
            ByteBuffer os = ByteBuffer.Wrap(bb.Bytes, bb.ReadIndex, bb.Size);             // 创建一个新的ByteBuffer,解码确认了才修改bb索引。

            while (os.Size > 0)
            {
                // 尝试读取协议类型和大小
                int type;
                int size;
                int readIndexSaved = os.ReadIndex;

                if (os.Size >= 8)                 // protocl header size.
                {
                    type = os.ReadInt4();
                    size = os.ReadInt4();
                }
                else
                {
                    // SKIP! 只有协议发送被分成很小的包,协议头都不够的时候才会发生这个异常。几乎不可能发生。
                    //bb.ReadIndex = readIndexSaved;
                    return;
                }

                // 以前写过的实现在数据不够之前会根据type检查size是否太大。
                // 现在去掉协议的最大大小的配置了.由总的参数 SocketOptions.InputBufferMaxProtocolSize 限制。
                // 参考 AsyncSocket
                if (size < 0 || size > os.Size)
                {
                    // 数据不够时检查。这个检测不需要严格的。如果数据够,那就优先处理。
                    if (size < 0 || size > service.SocketOptions.InputBufferMaxProtocolSize)
                    {
                        var pName = service.FindProtocolFactoryHandle(type)?.Factory().GetType().FullName;
                        throw new Exception($"Decode InputBufferMaxProtocolSize '{service.Name}' p='{pName}' type={type} size={size}");
                    }

                    // not enough data. try next time.
                    bb.ReadIndex = readIndexSaved;
                    return;
                }

                // 直接使用os,可以少创建对象,否则 Wrap 一个更安全:
                // ByteBuffer.Wrap(os.Bytes, os.ReadIndex, size)
                // 使用Wrap的话,记得手动增加: os.ReadIndex += size;
                Service.ProtocolFactoryHandle factoryHandle = service.FindProtocolFactoryHandle(type);
                if (null != factoryHandle)
                {
                    Protocol p = factoryHandle.Factory();
                    p.Service = service;
                    p.Decode(os);
                    p.Sender    = so;
                    p.UserState = so.UserState;
                    p.Dispatch(service, factoryHandle);
                    continue;
                }
                // 优先派发c#实现,然后尝试lua实现,最后UnknownProtocol。
                if (null != toLua)
                {
                    if (toLua.DecodeAndDispatch(service, so.SessionId, type, os))
                    {
                        continue;
                    }
                }
                service.DispatchUnknownProtocol(so, type, ByteBuffer.Wrap(os.Bytes, os.ReadIndex, size));
                os.ReadIndex += size;
            }
            bb.ReadIndex = os.ReadIndex;
        }