public static RPCEntry Pop(RPCHandler handler, params object[] args) { RPCEntry rpcEntry = POOL.Pop(); rpcEntry.handler = handler; rpcEntry.args = args; return(rpcEntry); }
/// <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); }
/// <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); }
/// <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); }
/// <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); } }
public static void Push(RPCEntry rpcEntry) => POOL.Push(rpcEntry);