예제 #1
0
        public static RPCEntry Pop(RPCHandler handler, params object[] args)
        {
            RPCEntry rpcEntry = POOL.Pop();

            rpcEntry.handler = handler;
            rpcEntry.args    = args;
            return(rpcEntry);
        }
예제 #2
0
        /// <summary>
        /// 发送消息到指定的session
        /// </summary>
        /// <param name="sessionID">session id</param>
        /// <param name="msg">消息</param>
        /// <param name="rpcEntry">RPC描述</param>
        /// <param name="transTarget">转发目标</param>
        /// <param name="nsid">转发的网络id</param>
        public bool Send(uint sessionID, IMessage msg, RPCEntry rpcEntry = null, Protos.MsgOpts.Types.TransTarget transTarget = Protos.MsgOpts.Types.TransTarget.Undefine, ulong nsid = 0u)
        {
            INetSession session = this.GetSession(sessionID);

            if (session == null)
            {
                return(false);
            }
            (( NetSessionBase )session).Send(msg, rpcEntry, transTarget, nsid);
            return(true);
        }
예제 #3
0
        /// <summary>
        /// 发送数据
        /// 线程不安全,不建议异步调用
        /// </summary>
        /// <param name="message">消息体</param>
        /// <param name="rpcEntry">RPC回调函数</param>
        /// <param name="transTarget">转发目标</param>
        /// <param name="nsid">转发的网络ID</param>
        public void Send(IMessage message, RPCEntry rpcEntry          = null,
                         Protos.MsgOpts.Types.TransTarget transTarget = Protos.MsgOpts.Types.TransTarget.Undefine,
                         ulong nsid = 0)
        {
            StreamBuffer buffer = this._bufferPool.Pop();

            buffer.Write(( int )message.GetMsgID());

            Protos.MsgOpts opts = message.GetMsgOpts();
            System.Diagnostics.Debug.Assert(opts != null, "invalid message options");

            if (transTarget != Protos.MsgOpts.Types.TransTarget.Undefine)
            {
                opts.Flag |= 1 << 3;                                  //mark as transpose
                opts.Flag |= ( uint )(1 << (3 + ( int )transTarget)); //mark trans target
            }
            if (nsid > 0)
            {
                opts.Transid = nsid;
            }

            if ((opts.Flag & (1 << ( int )Protos.MsgOpts.Types.Flag.Rpc)) > 0)                   //如果是rpc消息,记下消息序号等待回调
            {
                //只有rpc才写入序号
                if (nsid == 0)
                {
                    opts.Pid = this._pid++;                     //注意这里线程不安全
                }
                if (rpcEntry != null)
                {
                    if (this._pidToRPCEntries.ContainsKey(opts.Pid))
                    {
                        Logger.Warn("message id collision!!");
                    }
                    else
                    {
                        //rpcEntry.time = 0;
                        //记录回调函数
                        this._pidToRPCEntries[opts.Pid] = rpcEntry;
                        this._rpcEntries.Add(rpcEntry);
                    }
                }
            }

            message.WriteTo(buffer.ms);

            this.Send(buffer.GetBuffer(), 0, buffer.length);
            this._bufferPool.Push(buffer);
        }
예제 #4
0
 /// <summary>
 /// 发送消息到指定的session类型
 /// </summary>
 /// <param name="sessionType">session类型</param>
 /// <param name="msg">消息</param>
 /// <param name="rpcEntry">RPC描述</param>
 /// <param name="transTarget">转发目标</param>
 /// <param name="nsid">转发的网络id</param>
 /// <param name="all">是否在查询消息类型时对所有结果生效</param>
 public bool Send(SessionType sessionType, IMessage msg, RPCEntry rpcEntry = null,
                  Protos.MsgOpts.Types.TransTarget transTarget             = Protos.MsgOpts.Types.TransTarget.Undefine,
                  ulong nsid = 0u, bool all = true)
 {
     if (!this._typeToSession.TryGetValue(sessionType, out List <NetSessionBase> sessions))
     {
         return(false);
     }
     if (!all)
     {
         sessions[0].Send(msg, rpcEntry, transTarget, nsid);
     }
     else
     {
         foreach (NetSessionBase session in sessions)
         {
             session.Send(msg, rpcEntry, transTarget, nsid);
         }
     }
     return(true);
 }
예제 #5
0
        /// <summary>
        /// 接收消息后的处理函数
        /// </summary>
        /// <param name="data">接收的数据</param>
        /// <param name="offset">数据偏移量</param>
        /// <param name="size">数据长度</param>
        protected override void OnRecv(byte[] data, int offset, int size)
        {
            int len = data.Length;

            if (len - offset < sizeof(int))
            {
                Logger.Warn("invalid msg.");
                return;
            }
            //剥离消息ID
            Protos.MsgID msgID = (Protos.MsgID)ByteUtils.Decode32i(data, offset);
            //判断是否需要阻断该消息
            if (this.ShouldBlockMsg(msgID))
            {
                return;
            }
            offset += sizeof(int);
            size   -= offset;

            //解码消息
            IMessage message;

            try
            {
                message = ProtoCreator.DecodeMsg(msgID, data, offset, size);
            }
            catch (Exception e)
            {
                Logger.Warn($"decode message failed:{e}");
                return;
            }
            //检查第一个字段是否Protos.MsgOpts类型
            Protos.MsgOpts opts = message.GetMsgOpts();
            System.Diagnostics.Debug.Assert(opts != null, "invalid msg options");

            if ((opts.Flag & (1 << ( int )Protos.MsgOpts.Types.Flag.Trans)) > 0)                   //这是一条转发消息
            {
                //去掉转发标记
                //opts.Flag &= ~( uint ) Protos.MsgOpts.Types.Flag.Trans;

                //后2位为转发目标
                Protos.MsgOpts.Types.TransTarget transTarget = (Protos.MsgOpts.Types.TransTarget)((opts.Flag >> 4) & 0xf);
                //如果不是转发的目标
                if (!this.owner.IsTransTarget(transTarget))
                {
                    this.TransMsg(transTarget, opts.Transid, message);
                    return;
                }
            }
            //是否RPC消息
            if ((opts.Flag & (1 << ( int )Protos.MsgOpts.Types.Flag.Resp)) > 0)
            {
                if (this._pidToRPCEntries.TryGetValue(opts.Rpid, out RPCEntry rpcEntry))
                {
                    this._pidToRPCEntries.Remove(opts.Rpid);
                    this._rpcEntries.Remove(rpcEntry);
                    rpcEntry.handler(this, message, rpcEntry.args);                      //调用回调函数
                    RPCEntry.Push(rpcEntry);
                }
                else
                {
                    Logger.Warn($"RPC handler not found with message:{msgID}");
                }
            }
            else
            {
                this.DispatchMessage(msgID, message);
            }
        }
예제 #6
0
 public static void Push(RPCEntry rpcEntry) => POOL.Push(rpcEntry);