Пример #1
0
        public RockRouter(ushort router, ushort port)
        {
            _localVIP = new VirtuaIP()
            {
                Router = router,
                Node   = uint.MaxValue
            };

            //绑定本地地址
            _routerHost = "tcp://*:" + port.ToString();
        }
Пример #2
0
        internal RockWorker(VirtuaIP localVIP, string remoteAddress)
        {
            _localVIP = localVIP;

            _nextVIP = new VirtuaIP()
            {
                Router = localVIP.Router,
                Node   = uint.MaxValue //运算后节点所能取得最大数:16777215
            };

            _context       = ZmqContext.Create();
            _remoteAddress = remoteAddress;
        }
Пример #3
0
            private void Received()
            {
                using (ZmqSocket clientSocket = _context.CreateSocket(SocketType.REP))
                {
                    clientSocket.Identity          = BitConverter.GetBytes(_localPort);
                    clientSocket.SendHighWatermark = 10000;

                    bool isConnected = false;
                    while (!isConnected)
                    {
                        try
                        {
                            clientSocket.Connect(_inprocHost);
                            isConnected = true;
                        }
                        catch
                        {
                            Thread.Sleep(500);
                        }
                    }

                    try
                    {
                        while (_isRunning)
                        {
                            ZmqMessage zmqMessage = clientSocket.ReceiveMessage(new TimeSpan(0, 2, 0));
                            if (zmqMessage.FrameCount == 0)
                            {
                                //一分钟内没有收到任何消息,自行关闭
                                _isRunning = false;
                                continue;
                            }

                            VirtuaIP originVIP  = new VirtuaIP(zmqMessage[0].Buffer);
                            ushort   originPort = (ushort)BitConverter.ToInt16(zmqMessage[2].Buffer, 0);

                            byte[] respMsg = DealMessage(zmqMessage[zmqMessage.FrameCount - 1].Buffer);

                            //向客户端返回数据
                            clientSocket.SendMore(originVIP.ToBytes());
                            clientSocket.SendMore(BitConverter.GetBytes(originPort));
                            clientSocket.SendMore(BitConverter.GetBytes(_localPort));
                            clientSocket.Send(respMsg);
                        }
                    }
                    catch (ThreadInterruptedException) { }
                }

                //自行关闭释放资源
                Dispose(false);
            }
Пример #4
0
        private void Send(VirtuaIP destVIP, ushort destPort, byte[] data)
        {
            /*
             * 发送数据--共三帧
             * 0、空帧
             * 1、目的地址
             * 2、目的端口
             * 3、源端口
             * 4、数据
             * */

            _sendDealer.SendMore(_emptyFrame);
            _sendDealer.SendMore(destVIP.ToBytes());
            _sendDealer.SendMore(BitConverter.GetBytes(destPort));
            _sendDealer.SendMore(BitConverter.GetBytes(_receiverVPort));
            _sendDealer.Send(data);
        }
Пример #5
0
        public static RockWorker CreateRockWorker(ushort router, uint node, string remoteAddress)
        {
            _localVIP = new VirtuaIP()
            {
                Router = router,
                Node   = node,
            };

            //加载通信所需DynClass
            DynClassLoader.LoadDynClass();

            if (_worker != null)
            {
                throw new ApplicationException("RockWorker已经创建完成,不需要再次创建");
            }
            _worker = new RockWorker(_localVIP, remoteAddress);
            _worker.Start();
            return(_worker);
        }
Пример #6
0
        private void Send(VirtuaIP receiverVIP, ushort destVPort, byte[] reqData)
        {
            if (_reqSocket == null)
            {
                throw new ApplicationException("请你先启动RpcClient");
            }

            /*
             * 发送数据--共三帧
             * 1、目的地址
             * 2、目的端口
             * 3、源端口
             * 4、数据
             * */
            _reqSocket.SendMore(_emptyFrame);
            _reqSocket.SendMore(receiverVIP.ToBytes());
            _reqSocket.SendMore(BitConverter.GetBytes(destVPort));
            _reqSocket.SendMore(BitConverter.GetBytes(_localPort));
            _reqSocket.Send(reqData);
        }
Пример #7
0
        //destVIP 为接收消息的originVIP destPort为接收消息的originPort
        private void Send(VirtuaIP destVIP, ushort destPort, byte[] data)
        {
            //轮流使用队列中的socket(初始化时是300个)
            ZmqSocket sendSocket = _socketQueue.Dequeue() as ZmqSocket;

            /*
             * 发送数据--共三帧
             * 0、空帧
             * 1、目的地址
             * 2、目的端口
             * 3、源端口
             * 4、数据
             * */
            sendSocket.SendMore(_emptyFrame);
            sendSocket.SendMore(destVIP.ToBytes());
            sendSocket.SendMore(BitConverter.GetBytes(destPort));
            sendSocket.SendMore(BitConverter.GetBytes(_localPort));
            sendSocket.Send(data);
            _socketQueue.Enqueue(sendSocket);
        }
Пример #8
0
        /// <summary>
        /// 处理接受数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void ReceiveReady(object sender, SocketEventArgs e)
        {
            ZmqSocket  socket     = e.Socket;
            ZmqMessage zmqMessage = socket.ReceiveMessage();

            /*
             * 接收数据--共三帧
             * 1、源地址(发送数据的地址 路由号.节点号)
             * 2、端口
             * 3、数据
             * 这里的接收数据是和发送数据相一致的见上面的Send方法 */
            VirtuaIP originVIP  = new VirtuaIP(zmqMessage[1].Buffer);
            ushort   originPort = (ushort)BitConverter.ToInt16(zmqMessage[3].Buffer, 0);

            object resultMsg = DealRepMessage(zmqMessage[4].Buffer);

            if (OnDataReceived != null)
            {
                OnDataReceived(resultMsg);
            }
        }
Пример #9
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);
            }
        }
Пример #10
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;
            }
        }
Пример #11
0
        /// <summary>
        /// 文件下载
        /// </summary>
        /// <param name="recvAddress">服务端机器的地址</param>
        /// <param name="savePath">文件在本地的保存路径</param>
        /// <param name="downloadPath">要下载的文件在服务端的路径</param>
        public void FileDownload(string recvAddress, string savePath, string downloadPath)
        {
            #region 前置检查
            if (_isWorking)
            {
                throw new FtpException("一个FtpClient不能同时执行多个任务");
            }

            //验证本地是否已有同名文件
            if (File.Exists(Path.Combine(savePath, Path.GetFileName(downloadPath))))
            {
                throw new FtpException(savePath + "目录中已存在同名文件");
            }
            #endregion 前置检查

            #region 获取文件的基本信息
            _remoteAddress = new VirtuaIP(recvAddress);
            _serverPort    = GetServerPort("FileDownload");
            _isWorking     = true;

            //发送下载文件的请求
            long      fileSize     = 0; //文件大小(字节)
            long      remaining    = 0; //剩余未下载的文件大小
            DynObject fileFragment = RequestDownload(_serverPort, downloadPath);
            fileSize = remaining = (long)fileFragment["FileLength"];

            #endregion 获取文件的基本信息

            FileStream writeFileStream = null;
            _isCancelDownload = false;

            while (remaining >= 0 && _isWorking)
            {
                if (_isCancelDownload)
                {
                    fileFragment["State"] = (byte)103;
                }

                switch ((byte)fileFragment["State"])
                {
                case 100:
                    string tempFile = Path.Combine(savePath, fileFragment["MD5"] + ".temp");

                    //如果存在该文件的临时文件,则进行断点续传,否则以MD5为名字创建临时文件开始传送数据
                    if (File.Exists(tempFile))
                    {
                        writeFileStream       = new FileStream(tempFile, FileMode.Open);
                        fileFragment["MsgID"] = (int)(writeFileStream.Length / _bufferLength);
                        fileFragment["State"] = (byte)101;
                        fileFragment["Data"]  = null;
                    }
                    else
                    {
                        writeFileStream       = new FileStream(tempFile, FileMode.Create);
                        fileFragment["MsgID"] = 0;
                        fileFragment["State"] = (byte)101;
                        fileFragment["Data"]  = null;
                    }
                    remaining = fileSize - (int)fileFragment["MsgID"] * _bufferLength;
                    break;

                case 101:     //文件传送中
                    writeFileStream.Seek((int)fileFragment["MsgID"] * _bufferLength, SeekOrigin.Begin);
                    writeFileStream.Write(fileFragment["Data"] as byte[], 0, (int)fileFragment["DataLength"]);

                    remaining = fileSize - ((int)fileFragment["MsgID"] * _bufferLength + (int)fileFragment["DataLength"]);
                    if (remaining <= 0)
                    {
                        //文件下载结束
                        fileFragment["State"] = (byte)102;

                        writeFileStream.Flush();
                        writeFileStream.Close();
                        writeFileStream = null;
                        _isWorking      = false;

                        //校验文件传送是否正确
                        string path        = Path.Combine(savePath, fileFragment["MD5"] as string + ".temp");
                        string tempFileMD5 = GetMD5HashFromFile(path);

                        if (tempFileMD5 == fileFragment["MD5"] as string)
                        {
                            File.Move(path, Path.Combine(savePath, fileFragment["FileName"] as string));
                        }
                        else
                        {
                            File.Delete(path);
                            throw new FtpException("文件未能成功下载");
                        }
                    }

                    fileFragment["MsgID"]      = (int)fileFragment["MsgID"] + 1;
                    fileFragment["DataLength"] = 0;
                    fileFragment["Data"]       = null;
                    break;

                case 103:     //中断文件传送
                    fileFragment["DataLength"] = 0;
                    fileFragment["Data"]       = null;

                    writeFileStream.Flush();
                    writeFileStream.Close();
                    writeFileStream = null;
                    _isWorking      = false;
                    break;

                case 105:     //服务端发生异常
                    writeFileStream.Flush();
                    writeFileStream.Close();
                    writeFileStream = null;
                    _isWorking      = false;
                    throw new FtpException(fileFragment["ExcepMsg"] as string);
                }

                //向外界通知文件床送进度
                if (ProgressEvent != null)
                {
                    ProgressEvent(fileSize, fileSize - remaining);
                }

                //发送请求下一个包数据(发生异常告诉对方关闭文件流)
                TSerializer serialize = new TBinarySerializer();
                DynSerialize.WriteDynObject(serialize, fileFragment);
                byte[] buffer = serialize.ToBytes();
                serialize.Flush();

                Send(_serverPort, buffer);
                ZmqMessage message = _ftpSocket.ReceiveMessage(new TimeSpan(0, 1, 30));
                if (message.FrameCount == 0)
                {
                    writeFileStream.Close();
                    writeFileStream = null;
                    _isWorking      = false;
                    ReStart();
                    throw new TimeoutException("发送超时,请检查你的网络是否有问题,稍后重新下载");
                }

                serialize = new TBinarySerializer();
                serialize.FromBytes(message[message.FrameCount - 1].Buffer);
                fileFragment = DynSerialize.ReadDynObject(serialize);
                serialize.Flush();
            }
        }
Пример #12
0
        /// <summary>
        /// 文件上传
        /// </summary>
        /// <param name="recvAddress">服务端机器的地址</param>
        /// <param name="filePath">准备上传的文件</param>
        /// <param name="savePath">文件在服务端的保存路径</param>
        public void FileUpload(string recvAddress, string filePath, string savePath)
        {
            if (_isWorking)
            {
                throw new FtpException("一个FtpClient不能同时执行多个任务");
            }

            CheckPostfix(filePath);//检查上传的文件类型是否合法

            string md5 = GetMD5HashFromFile(filePath);

            _remoteAddress = new VirtuaIP(recvAddress);
            _serverPort    = GetServerPort("FileUpload");

            using (FileStream fStream = File.OpenRead(filePath))
            {
                long   fileSize  = fStream.Length; //文件数据长度
                long   remaining = fileSize;       // 剩余没上传的数据长度
                byte[] buffer    = new byte[_bufferLength];

                //构建文件片段
                DynObject fileFragment = new DynObject("FileFragment");
                fileFragment["MD5"]        = md5;
                fileFragment["FileName"]   = Path.GetFileName(filePath);
                fileFragment["Extension"]  = Path.GetExtension(filePath);
                fileFragment["Path"]       = savePath;
                fileFragment["DataLength"] = 0;
                fileFragment["MsgID"]      = -1;
                fileFragment["State"]      = (byte)0;

                _isCancelUpload = false;
                _isWorking      = true;
                int offset = 0;

                while (remaining >= 0 && _isWorking)
                {
                    if (_isCancelUpload)
                    {
                        fileFragment["State"] = (byte)3;
                    }

                    switch ((byte)fileFragment["State"])
                    {
                    case 0:     //文件传送开始
                        //第一次发送文件,发送一些基本信息(如文件名等)
                        fileFragment["DataLength"] = 0;
                        fileFragment["Data"]       = null;
                        break;

                    case 1:     //文件传送中
                        fStream.Seek((int)fileFragment["MsgID"] * _bufferLength, SeekOrigin.Begin);
                        fileFragment["DataLength"] = fStream.Read(buffer, offset, buffer.Length - offset);
                        fileFragment["Data"]       = buffer;

                        //重置剩余数据长度
                        remaining = fileSize - ((int)fileFragment["MsgID"] * _bufferLength + (int)fileFragment["DataLength"]);
                        if (remaining == 0)
                        {
                            _isWorking = false;

                            remaining             = -1;
                            fileFragment["State"] = (byte)2;
                        }
                        break;

                    case 3:     //中断文件传送
                        fileFragment["DataLength"] = 0;
                        fileFragment["Data"]       = null;

                        _isWorking = false;
                        break;
                    }

                    //序列化
                    TSerializer serializer = new TBinarySerializer();
                    DynSerialize.WriteDynObject(serializer, fileFragment);
                    byte[] data = serializer.ToBytes();
                    serializer.Flush();

                    DynObject repFragment = Transfer(_serverPort, data, 0);
                    fileFragment["State"] = repFragment["State"];
                    fileFragment["MsgID"] = repFragment["MsgID"];

                    //向外界通知文件传送进度
                    if (ProgressEvent != null)
                    {
                        ProgressEvent(fileSize, fileSize - remaining);
                    }
                }
            }
        }
Пример #13
0
        /// <summary>
        /// 分发接收到的数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ReceiveReady(object sender, SocketEventArgs e)
        {
            ZmqSocket  socket     = e.Socket;
            ZmqMessage zmqMessage = socket.ReceiveMessage();
            VirtuaIP   destVIP    = new VirtuaIP(zmqMessage[2].Buffer);

            //如果目标地址和本地路由一致转发到应用程序 ,如果不一致转发到Router
            if (destVIP.Router == _localVIP.Router && destVIP.Node == _localVIP.Node)
            {
                if (zmqMessage.FrameCount == 6)
                {
                    /*
                     * 把收到的本地数据转发到应用程序--共六帧数据
                     * 0、目的端口
                     * 1、空帧
                     * 2、源地址
                     * 3、目的端口
                     * 4、源端口
                     * 5、数据
                     * */
                    socket.SendMore(zmqMessage[3].Buffer);
                    socket.SendMore(zmqMessage[1].Buffer);
                    socket.SendMore(zmqMessage[2].Buffer);
                    socket.SendMore(zmqMessage[3].Buffer);
                    socket.SendMore(zmqMessage[4].Buffer);
                    socket.Send(zmqMessage[5].Buffer);
                }
                else if (zmqMessage.FrameCount == 7)
                {
                    /*
                     * 把收到的远端数据转发到应用程序--共五帧数据
                     * 0、目的端口
                     * 1、空帧
                     * 2、源地址
                     * 3、目的端口
                     * 4、源端口
                     * 5、数据
                     * */
                    socket.SendMore(zmqMessage[4].Buffer);
                    socket.SendMore(zmqMessage[1].Buffer);
                    socket.SendMore(zmqMessage[3].Buffer);
                    socket.SendMore(zmqMessage[4].Buffer);
                    socket.SendMore(zmqMessage[5].Buffer);
                    socket.Send(zmqMessage[6].Buffer);
                }
                //不符合要求的帧丢弃
            }
            else if (zmqMessage.FrameCount == 6)
            {
                /*
                 * 转发到Router--共七帧数据
                 * 0、下一跳地址
                 * 1、空帧
                 * 2、目的地址
                 * 3、源地址
                 * 4、目的端口
                 * 5、源端口
                 * 6、数据
                 * */
                socket.SendMore(_nextVIP.ToBytes());//下一跳地址
                socket.SendMore(zmqMessage[1].Buffer);
                socket.SendMore(zmqMessage[2].Buffer);
                socket.SendMore(_localVIP.ToBytes());
                socket.SendMore(zmqMessage[3].Buffer);
                socket.SendMore(zmqMessage[4].Buffer);
                socket.Send(zmqMessage[5].Buffer);
            }
            //不符合要求的帧丢弃
        }
Пример #14
0
        /// <summary>
        /// 根据消息的目的地址,对消息进行转发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ReceiveReady(object sender, SocketEventArgs e)
        {
            ZmqSocket  socket     = e.Socket;
            ZmqMessage zmqMessage = socket.ReceiveMessage();

            //不符合要求的包直接丢掉
            if (zmqMessage.FrameCount != 7)
            {
                return;
            }

            VirtuaIP destVIP = new VirtuaIP(zmqMessage[2].Buffer);

            #region 统计收到的数据包数量,转发速度p/s(每秒多少个包),并通知主线程更新界面
            //byte[] data = zmqMessage[6].Buffer;
            //byte flage = data[0];
            //switch (flage)
            //{
            //    case 0: count++; count = 1; break;
            //    case 1: count++; break;
            //    case 2: count++; ; break;
            //}
            //if (DataAnalysis != null)
            //    DataAnalysis("in", count);

            #endregion

            #region 转发数据

            if (destVIP.Router == _localVIP.Router)
            {
                if (destVIP.Node == _localVIP.Node)
                {
                    //Router自己处理
                    Console.WriteLine("我的消息:{0}", Encoding.Unicode.GetString(zmqMessage[5].Buffer));
                }
                else
                {
                    /*
                     * 接收数据--共六帧数据
                     * 0、目的地址
                     * 1、空帧
                     * 2、目的地址
                     * 3、源地址
                     * 4、目的端口
                     * 5、源端口
                     * 6、数据
                     * */
                    socket.SendMore(zmqMessage[2].Buffer);
                    socket.SendMore(zmqMessage[1].Buffer);
                    socket.SendMore(zmqMessage[2].Buffer);
                    socket.SendMore(zmqMessage[3].Buffer);
                    socket.SendMore(zmqMessage[4].Buffer);
                    socket.SendMore(zmqMessage[5].Buffer);
                    socket.Send(zmqMessage[6].Buffer);

                    //如果推断不错的话,这里应该是发往本机的应用程序服务器端
                }
            }
            else
            {
                /*
                 * 转发到Router--共七帧数据
                 * 0、新的下一跳Router地址
                 * 1、空帧
                 * 2、目的地址
                 * 3、源地址
                 * 4、目的端口
                 * 5、源端口
                 * 6、数据
                 * */

                //转发的下一个Router
                //得到下一跳地址
                ushort nodeID = destVIP.Router;
                //TODO 此处可能得不到下一跳节点,因为目的节点不可到达,异常捕获比一般的判断速度慢10倍
                ushort nextRouterID = _nextTripRouterDic[nodeID];

                //得到连接到下一跳router的dealer
                RouterDealer dealer = _dealers[nextRouterID];

                //dealer.Socket.SendMore(nextRouterVIP.ToBytes());//下一跳地址
                dealer.Socket.SendMore(zmqMessage[1].Buffer);
                dealer.Socket.SendMore(zmqMessage[2].Buffer);
                dealer.Socket.SendMore(zmqMessage[3].Buffer);
                dealer.Socket.SendMore(zmqMessage[4].Buffer);
                dealer.Socket.SendMore(zmqMessage[5].Buffer);
                dealer.Socket.Send(zmqMessage[6].Buffer);

                //if (DataAnalysis != null)
                //    DataAnalysis("out", count);
            }

            #endregion 转发数据
        }
Пример #15
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;
                    }
                }
            }
        }
Пример #16
0
        private void OnServer()
        {
            using (ZmqSocket serverSocket = _context.CreateSocket(SocketType.DEALER))
            {
                serverSocket.Identity          = BitConverter.GetBytes(_ftpServerPort);
                serverSocket.SendHighWatermark = 100000;

                bool isConnected = false;
                while (!isConnected)
                {
                    try
                    {
                        serverSocket.Connect(_inprocHost);
                        isConnected = true;
                    }
                    catch
                    {
                        Thread.Sleep(500);
                    }
                }

                while (_isRunning)
                {
                    string   responseData = null;
                    VirtuaIP originVIP    = null;
                    ushort   originPort   = 0;

                    try
                    {
                        ZmqMessage zmqMessage = serverSocket.ReceiveMessage(TimeSpan.MaxValue);

                        if (zmqMessage.FrameCount == 0)
                        {
                            throw new FtpException();
                        }
                        originVIP  = new VirtuaIP(zmqMessage[1].Buffer);
                        originPort = (ushort)BitConverter.ToInt16(zmqMessage[3].Buffer, 0);
                        byte[] requestMsg = zmqMessage[zmqMessage.FrameCount - 1].Buffer;

                        //当有传送文件的请求时,创建一个Client和客户端通信,并把Client的端口返回给客户端--TODO
                        ushort port        = RockContext.GetAvailablePort();
                        string requestType = _encoding.GetString(requestMsg);

                        Client client = new Client(port, _context, this, requestType);
                        client.OnException = OnException;
                        client.Start();

                        responseData = "Success:" + port;
                        Thread.Sleep(2000);
                    }
                    catch (ThreadInterruptedException)
                    {
                        continue;
                    }
                    catch (FtpException)
                    {
                        continue;
                    }
                    catch (Exception e)
                    {
                        if (OnException != null)
                        {
                            OnException(e);
                        }
                        responseData = "Error:" + e.Message;
                    }

                    /*
                     * 发送数据--共三帧
                     * 0、空帧
                     * 1、目的地址
                     * 2、目的端口
                     * 3、源端口
                     * 4、数据
                     * */
                    serverSocket.SendMore(_emptyFrame);
                    serverSocket.SendMore(originVIP.ToBytes());
                    serverSocket.SendMore(BitConverter.GetBytes(originPort));
                    serverSocket.SendMore(BitConverter.GetBytes(_ftpServerPort));
                    serverSocket.Send(_encoding.GetBytes(responseData));
                }
            }
        }
Пример #17
0
        public void Send(string recvAddress, ushort destVPort, string data)
        {
            VirtuaIP receiverVIP = new VirtuaIP(recvAddress);

            Send(receiverVIP, destVPort, Encoding.UTF8.GetBytes(data));
        }