Exemplo n.º 1
0
        /// <summary>
        /// 处理返回消息
        /// </summary>
        /// <param name="msgData">返回消息</param>
        private object DealRepMessage(byte[] msgData)
        {
            TSerializer serializerResp = new TBinarySerializer();

            serializerResp.FromBytes(msgData);
            TMessage respMsg = serializerResp.ReadMessageBegin();

            if (respMsg.Type == TMessageType.Exception)
            {
                this.RaiseDealMessageExceptionEvent(TApplicationException.Read(serializerResp));

                serializerResp.ReadMessageEnd();
                serializerResp.Flush();

                return(null);;
            }

            if (respMsg.Type != TMessageType.RpcReply)
            {
                this.RaiseDealMessageExceptionEvent(new ApplicationException("非法的返回类型:" + respMsg.Type.ToString()));

                serializerResp.ReadMessageEnd();
                serializerResp.Flush();

                return(null);
            }

            string[]          temp = respMsg.Name.Split('_');
            DynMethodInstance dynMethodInstance = new DynMethodInstance(temp[0], temp[1]);

            try
            {
                dynMethodInstance.Result = DynSerialize.ReadResult(serializerResp, dynMethodInstance);
            }
            catch (Exception ex)
            {
                this.RaiseDealMessageExceptionEvent(ex);

                serializerResp.ReadMessageEnd();
                serializerResp.Flush();
            }

            // 消息结束
            serializerResp.ReadMessageEnd();
            serializerResp.Flush();
            return(dynMethodInstance.Result);
        }
Exemplo n.º 2
0
        /// <summary>
        /// 远程方法调用
        /// </summary>
        /// <param name="recvAddress">接收节点的虚拟IP地址,如3.1/param>
        /// <param name="interfaceName">接口名称</param>
        /// <param name="methodName">方法名称</param>
        /// <param name="paramDict">参数字段</param>
        /// <param name="messageType">消息类型</param>
        public void Call(string recvAddress, ushort destVPort, string interfaceName, string methodName, Dictionary <string, object> paramDict, TMessageType messageType = TMessageType.RpcCall)
        {
            try
            {
                VirtuaIP receiverVIP = new VirtuaIP(recvAddress);
                string   msgID       = Guid.NewGuid().ToString();

                if (!InterfaceImplementMap.InterfaceAndImplementMap.ContainsKey(interfaceName))
                {
                    throw new ApplicationException("找不到接口" + interfaceName + "的具体实现!!");
                }

                //本地应用端口随机获取,目标端口确定
                TMessage          reqMsg            = new TMessage(interfaceName + "_" + methodName, messageType, msgID, -1, "", "", "", "");
                DynMethodInstance dynMethodInstance = new DynMethodInstance(interfaceName, methodName);
                TSerializer       serializerReq     = new TBinarySerializer();

                serializerReq.WriteMessageBegin(reqMsg);
                foreach (var para in paramDict)
                {
                    dynMethodInstance[para.Key] = para.Value;
                }

                DynSerialize.WriteDynMethodInstance(serializerReq, dynMethodInstance);
                serializerReq.WriteMessageEnd();
                byte[] reqData = serializerReq.ToBytes();

                serializerReq.Flush();

                Send(receiverVIP, destVPort, reqData);
            }
            catch (Exception ex)
            {
                this.RaiseDealMessageExceptionEvent(ex);
                throw new ApplicationException(ex.Message);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// 处理返回消息
        /// </summary>
        /// <param name="msgData">返回消息</param>
        private object DealRepMessage(byte[] msgData, string msgID, out bool isReceive)
        {
            //初始化序列化容器
            TSerializer serializerResp = new TBinarySerializer();

            //将数据读入序列化容器
            serializerResp.FromBytes(msgData);
            //从序列化容器中读取消息
            TMessage respMsg = serializerResp.ReadMessageBegin();

            //如果消息的id不对返回空值
            if (msgID != respMsg.MsgID)
            {
                //空方法
                serializerResp.ReadMessageEnd();
                serializerResp.Flush();

                isReceive = false;
                return(null);
            }

            //如果是异常消息
            if (respMsg.Type == TMessageType.Exception)
            {
                TApplicationException appException = TApplicationException.Read(serializerResp);
                this.RaiseDealMessageExceptionEvent(appException);

                serializerResp.ReadMessageEnd();
                serializerResp.Flush();

                throw appException;
            }
            //如果消息是远程调用回应
            if (respMsg.Type != TMessageType.RpcReply)
            {
                this.RaiseDealMessageExceptionEvent(new ApplicationException("非法的返回类型:" + respMsg.Type.ToString()));

                serializerResp.ReadMessageEnd();
                serializerResp.Flush();

                isReceive = true;
                return(null);
            }

            //构造方法的实例
            string[]          temp = respMsg.Name.Split('_');
            DynMethodInstance dynMethodInstance = new DynMethodInstance(temp[0], temp[1]);

            try
            {
                dynMethodInstance.Result = DynSerialize.ReadResult(serializerResp, dynMethodInstance);
            }
            catch (Exception ex)
            {
                this.RaiseDealMessageExceptionEvent(ex);

                serializerResp.ReadMessageEnd();
                serializerResp.Flush();
            }

            // 消息结束
            serializerResp.ReadMessageEnd();
            serializerResp.Flush();

            isReceive = true;
            return(dynMethodInstance.Result);
        }
Exemplo n.º 4
0
        /// <summary>
        /// 远程方法调用
        /// </summary>
        /// <param name="recvAddress">接收节点的虚拟IP地址,如3.1/param>
        /// <param name="interfaceName">接口名称</param>
        /// <param name="methodName">方法名称</param>
        /// <param name="paramDict">参数字段</param>
        /// <param name="liveLife">生命周期,以秒为单位</param>
        /// <param name="messageType">消息类型</param>
        /// <returns>服务端返回的数据或者null</returns>
        public object Call(string recvAddress, ushort destVPort, string interfaceName, string methodName, Dictionary <string, object> paramDict, short liveLife, TMessageType messageType = TMessageType.RpcCall)
        {
            object result = null;

            _msgID = _msgID < int.MaxValue ? ++_msgID : 0;

            try
            {
                VirtuaIP receiverVIP = new VirtuaIP(recvAddress);
                string   msgID       = _msgID.ToString();

                if (!InterfaceImplementMap.InterfaceAndImplementMap.ContainsKey(interfaceName))
                {
                    throw new ApplicationException("找不到接口" + interfaceName + "的具体实现!");
                }

                DynMethodInstance dynMethodInstance = new DynMethodInstance(interfaceName, methodName);
                TMessage          reqMsg            = new TMessage(interfaceName + "_" + methodName, messageType, msgID, liveLife, "", "", "", "");
                TSerializer       serializerReq     = new TBinarySerializer();
                //将消息头信息写入流
                serializerReq.WriteMessageBegin(reqMsg);
                foreach (var para in paramDict)
                {
                    dynMethodInstance[para.Key] = para.Value;
                }
                //将方法的实例写入流
                DynSerialize.WriteDynMethodInstance(serializerReq, dynMethodInstance);

                //什么都不做
                serializerReq.WriteMessageEnd();
                //将消息流转换成二进制流
                byte[] reqData = serializerReq.ToBytes();
                serializerReq.Flush();

                //发送消息
                Send(receiverVIP, destVPort, reqData);

                var timeout = new TimeSpan(0, 0, liveLife);
                //创建一个 Stopwatch 实例:使用 StartNew() 会创建一个 Stopwatch 实例并马上开始计时,即等效于如下代码:
                //Stopwatch sw2 = new Stopwatch();
                //sw2.Start();
                var  timer     = Stopwatch.StartNew();
                bool isReceive = false;

                do
                {
                    ZmqMessage zmqMessage = _reqSocket.ReceiveMessage(timeout - timer.Elapsed);
                    if (zmqMessage.FrameCount == 0)
                    {
                        throw new TimeoutException("调用超时,请检查网络是否联通!");
                    }
                    else
                    {
                        //zmqMessage[zmqMessage.FrameCount - 1].Buffer 只需要处理zmqMessage中最后一帧,这一帧存的是消息中的数据部分
                        result = DealRepMessage(zmqMessage[zmqMessage.FrameCount - 1].Buffer, msgID, out isReceive);

                        //消息ID不匹配且超时时间未到时,丢掉当前接收到的数据包,继续接受数据
                        if (isReceive)
                        {
                            return(result);
                        }
                    }
                }while (timer.Elapsed <= timeout);

                throw new TimeoutException("调用超时,请检查网络是否联通!");
            }
            catch (Exception ex)
            {
                this.RaiseDealMessageExceptionEvent(ex);
                throw;
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// 重载父类方法
        /// </summary>
        /// <param name="msgData">接收到的消息</param>
        private void DealMessage(object obj)
        {
            ZmqMessage zmqMessage = obj as ZmqMessage;
            //记录源地址和端口
            VirtuaIP originVIP  = new VirtuaIP(zmqMessage[1].Buffer);
            ushort   originPort = (ushort)BitConverter.ToInt16(zmqMessage[3].Buffer, 0);

            byte[] requestData = zmqMessage[zmqMessage.FrameCount - 1].Buffer;

            if (requestData != null && requestData.Length >= 4)
            {
                TSerializer serializer = new TBinarySerializer();
                serializer.FromBytes(requestData);

                // 获取消息
                TMessage msg = serializer.ReadMessageBegin();

                if (msg.Type == TMessageType.RpcCall || msg.Type == TMessageType.RpcOneway)
                {
                    //获取方法信息构造Method
                    string[]          temp           = msg.Name.Split('_');
                    DynMethodInstance methodInstance = null;
                    try
                    {
                        methodInstance = DynSerialize.ReadDynMethodInstance(serializer, temp[0], temp[1]);
                        serializer.ReadMessageEnd();
                        serializer.Flush();

                        Dictionary <string, object> paramValues = new Dictionary <string, object>();
                        //获取参数信
                        foreach (string paramName in methodInstance.DynMethod.GetParameterNames())
                        {
                            paramValues[paramName] = methodInstance[paramName];
                        }

                        string className      = InterfaceImplementMap.InterfaceAndImplementMap[temp[0]];
                        string methodFullName = className + "_" + temp[1];
                        //方法调用
                        object ret = DynTypeManager.MethodHandler(null, methodFullName, paramValues);

                        if (methodInstance.DynMethod.Result.DynType != DynType.Void)
                        {
                            methodInstance.Result = ret;
                        }

                        // 序列化返回结果
                        serializer = new TBinarySerializer();
                        TMessage respMsg = new TMessage(msg.Name, TMessageType.RpcReply, msg.MsgID, msg.LiveLife, "", "", "", "");
                        serializer.WriteMessageBegin(respMsg);
                        DynSerialize.WriteResult(serializer, methodInstance);
                        serializer.WriteMessageEnd();
                        byte[] respData = serializer.ToBytes();
                        serializer.Flush();

                        // 返回客户端
                        Send(originVIP, originPort, respData);
                    }
                    catch (Exception ex)
                    {
                        serializer.ReadMessageEnd();
                        serializer.Flush();

                        //如果服务端需要记录日志,则由本事件把异常信息发出
                        RaiseDealMessageExceptionEvent(ex);

                        byte[] returnData = ReturnExceptionToClient("RpcServer.DealMessageException", msg, ex.Message);
                        // 返回客户端
                        Send(originVIP, originPort, returnData);
                        return;
                    }
                }
            }
        }