Esempio n. 1
0
 internal MethodReply(MethodReply reply) : base(reply)
 {
 }
Esempio n. 2
0
        public static async Task <TResult> CallAsync <TResult>(this IConnection connection, string method, Func <string, System.Type> errorParametersType)
        {
            MethodReply <TResult> reply = await connection.CallMethodAsync <TResult>(method, errorParametersType, parameters : null, CallFlags.ThrowOnError);

            return(reply.parameters);
        }
Esempio n. 3
0
        public async Task <MethodReply <TResult> > CallMethodAsync <TResult>(string method, Func <string, System.Type> errorParametersType, object parameters, CallFlags flags)
        {
            try
            {
                int prevState = Interlocked.CompareExchange(ref _state, StateBusy, StateNone);
                if (prevState == StateBusy)
                {
                    throw new InvalidOperationException("Concurrent operations are not supported.");
                }
                else if (prevState == StateDisposed)
                {
                    throw new ObjectDisposedException(typeof(Connection).FullName);
                }
                if (!_connected)
                {
                    ParseAddress(_address, out _socket, out _endPoint);
                    await _socket.ConnectAsync(_endPoint);

                    _connected = true;
                }
                MethodCall <object> call = new MethodCall <object>
                {
                    parameters = parameters,
                    method     = method,
                    oneway     = false,
                    upgrade    = false
                };
                string serializedCall = JsonConvert.SerializeObject(call);
                await _socket.SendAsync(Encoding.UTF8.GetBytes(serializedCall), SocketFlags.None); // TODO: why didn't this throw without ConnectAsync

                await _socket.SendAsync(new byte[] { 0 }, SocketFlags.None);

                _memoryStream.SetLength(0);
                bool eom = false;
                do
                {
                    int length = await _socket.ReceiveAsync(_readBuffer.AsMemory(), SocketFlags.None);

                    if (length == 0)
                    {
                        throw new IOException("Unexpected end of stream.");
                    }
                    _memoryStream.Write(_readBuffer, 0, length);
                    for (int i = 0; i < length; i++)
                    {
                        if (_readBuffer[i] == 0)
                        {
                            eom = true;
                        }
                    }
                } while (!eom);
                _memoryStream.Position = 0;
                _streamReader.DiscardBufferedData();
                MethodReply reply = (MethodReply)_serializer.Deserialize(_streamReader, typeof(MethodReply));

                _memoryStream.Position = 0;
                _streamReader.DiscardBufferedData();
                MethodReply <TResult> result;
                if (reply.error != null)
                {
                    result = new MethodReply <TResult>(reply);
                    System.Type errorType = errorParametersType?.Invoke(reply.error);
                    if (errorType != null)
                    {
                        var replyWithErrorParameters = (MethodReply)_serializer.Deserialize(_streamReader, typeof(MethodReply <>).MakeGenericType(errorType));
                        result.ErrorParameters = replyWithErrorParameters.GetParameters();
                    }
                    if ((flags & CallFlags.ThrowOnError) != CallFlags.None)
                    {
                        result.ThrowOnError();
                    }
                }
                else
                {
                    result = (MethodReply <TResult>)_serializer.Deserialize(_streamReader, typeof(MethodReply <TResult>));
                }
                return(result);
            }
            catch
            {
                _socket?.Dispose();
                _connected = false;
                throw;
            }
            finally
            {
                int prevState = Interlocked.CompareExchange(ref _state, StateNone, StateBusy);
                if (prevState == StateDisposed)
                {
                    _socket?.Dispose();
                }
            }
        }