Beispiel #1
0
        private async static void RpcDo(AChannel channel, Opcode opcode, byte[] messageBytes)
        {
            byte[] opcodeBuffer;
            int    id = BitConverter.ToInt32(messageBytes, 2);

            byte[] idBuffer = BitConverter.GetBytes(id);
            try
            {
                opcodeBuffer = BitConverter.GetBytes((ushort)Opcode.RpcResponse);
                byte[] result = await World.Instance.GetComponent <MessageComponent>().RunAsync(opcode, messageBytes);

                channel.SendAsync(new List <byte[]> {
                    opcodeBuffer, idBuffer, result
                });
            }
            catch (Exception e)
            {
                opcodeBuffer = BitConverter.GetBytes((ushort)Opcode.RpcException);
                BinaryFormatter formatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.All));
                using (MemoryStream stream = new MemoryStream())
                {
                    formatter.Serialize(stream, e);
                    channel.SendAsync(new List <byte[]> {
                        opcodeBuffer, idBuffer, stream.ToArray()
                    });
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Rpc请求
        /// </summary>
        public Task <T> RpcCall <T, K>(string address, K request, int waitTime = 0)
        {
            AChannel channel = this.service.GetChannel(address);

            ++this.requestId;
            byte[] requestBuffer = MongoHelper.ToBson(request);
            Opcode opcode        = EnumHelper.FromString <Opcode>(request.GetType().Name);

            byte[] opcodeBuffer = BitConverter.GetBytes((ushort)opcode);
            byte[] idBuffer     = BitConverter.GetBytes(this.requestId);
            channel.SendAsync(new List <byte[]> {
                opcodeBuffer, idBuffer, requestBuffer
            });
            var tcs = new TaskCompletionSource <T>();

            this.requestCallback[this.requestId] = (messageBytes, status) =>
            {
                switch (status)
                {
                case RpcResponseStatus.Timeout:
                    tcs.SetException(new Exception($"rpc timeout {opcode} {MongoHelper.ToJson(request)}"));
                    return;

                case RpcResponseStatus.Exception:
                    BinaryFormatter formatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.All));
                    Exception       exception;
                    using (MemoryStream stream = new MemoryStream(messageBytes, 6, messageBytes.Length - 6))
                    {
                        exception = (Exception)formatter.Deserialize(stream);
                    }
                    tcs.SetException(exception);
                    return;
                }

                // RpcResponseStatus.Succee
                T response = MongoHelper.FromBson <T>(messageBytes, 6);
                tcs.SetResult(response);
            };

            if (waitTime > 0)
            {
                this.service.Timer.Add(TimeHelper.Now() + waitTime,
                                       () => { this.RpcCallback(channel, this.requestId, null, RpcResponseStatus.Timeout); });
            }
            return(tcs.Task);
        }