示例#1
0
文件: V5RPC.cs 项目: npuv5pp/V5RPC
        public void Run(Procedure proc)
        {
            if (isDisposed)
            {
                throw new ObjectDisposedException("V5Server");
            }
            breakFlag = false;
            while (!isDisposed && !breakFlag)
            {
                try
                {
                    var      endPoint = new IPEndPoint(IPAddress.Any, 0);
                    V5Packet inPacket;
                    {
                        var buffer = udpClient.Receive(ref endPoint);
                        using (var io = new MemoryStream(buffer))
                        {
                            inPacket = io.ReadV5Packet();
                        }
                    }

                    byte[] response;
                    if (lastResponse.requestId == inPacket.requestId)
                    {
                        response = lastResponse.response;
                    }
                    else
                    {
                        response = proc(inPacket.payload);
                        if (response == null)
                        {
                            response = new byte[0];
                        }
                        lastResponse.requestId = inPacket.requestId;
                        lastResponse.response  = response;
                    }

                    {
                        V5Packet outPacket = V5Packet.MakeResponsePacket(response, inPacket.requestId);
                        var      io        = new MemoryStream();
                        io.Write(outPacket);
                        var buffer = io.ToArray();
                        udpClient.Send(buffer, buffer.Length, endPoint);
                    }
                }
                catch (SocketException e)
                {
                    if (PrintDebugInfo)
                    {
                        Console.WriteLine(e.Message);
                    }
                }
            }
        }
示例#2
0
文件: V5RPC.cs 项目: npuv5pp/V5RPC
        public static V5Packet ReadV5Packet(this Stream io)
        {
            var packet = new V5Packet();
            var reader = new BinaryReader(io);

            packet.magic = reader.ReadUInt32();
            if (packet.magic != V5Packet.MAGIC)
            {
                throw new InvalidDataException($"Invalid magic {packet.magic}");
            }
            packet.requestId = new Guid(reader.ReadBytes(16));
            packet.flags     = reader.ReadByte();
            packet.length    = reader.ReadUInt16();
            packet.payload   = reader.ReadBytes(packet.length);
            return(packet);
        }
示例#3
0
文件: V5RPC.cs 项目: npuv5pp/V5RPC
        public byte[] Call(byte[] payload, int timeout = 10000, int retryInterval = 50)
        {
            var server = Server;

            if (server == null)
            {
                throw new InvalidOperationException("Server is not specified");
            }
            byte[] outBuffer;
            Guid   outGuid;

            {
                var packet = V5Packet.MakeRequestPacket(payload);
                var io     = new MemoryStream();
                io.Write(packet);
                outBuffer = io.ToArray();
                outGuid   = packet.requestId;
            }
            void SendMe()
            {
                udpClient.Send(outBuffer, outBuffer.Length, server);
            }

            var timeoutState = new TaskCompletionSource <bool>();
            var cts          = new CancellationTokenSource();
            var receiverTask = Task.Run(() =>
            {
                while (true)
                {
                    cts.Token.ThrowIfCancellationRequested();
                    try
                    {
                        IPEndPoint remote = new IPEndPoint(IPAddress.Any, 0);
                        var inBuffer      = udpClient.Receive(ref remote);
                        var io            = new MemoryStream(inBuffer);
                        var packet        = io.ReadV5Packet();
                        if (packet.Reply && packet.requestId == outGuid)
                        {
                            return(packet.payload);
                        }
                    }
                    catch (SocketException e)
                    {
                        if (PrintDebugInfo)
                        {
                            Console.WriteLine(e.Message);
                        }
                    }
                }
            }, cts.Token);

            SendMe();
            var   startTime = DateTime.Now;
            Timer timer     = null;

            timer = new Timer((object state) =>
            {
                var currentTime = DateTime.Now;
                var diffTime    = currentTime - startTime;
                if (diffTime.TotalMilliseconds >= timeout)
                {
                    timeoutState.SetResult(true);
                    cts.Cancel();
                    timer.Dispose();
                }
                else
                {
                    SendMe();
                }
            }, null, retryInterval, retryInterval);
            Task.WaitAny(new Task[] { receiverTask, timeoutState.Task });
            timer.Dispose();
            if (timeoutState.Task.IsCompleted)
            {
                throw new TimeoutException();
            }
            return(receiverTask.Result);
        }