thrifty-runtime/src/main/java/com/microsoft/thrifty/service/ClientBase.java
final Object invokeRequest(MethodCall<?> call) throws Exception {
        boolean isOneWay = call.callTypeId == TMessageType.ONEWAY;
        int sid = seqId.incrementAndGet();

        protocol.writeMessageBegin(call.name, call.callTypeId, sid);
        call.send(protocol);
        protocol.writeMessageEnd();
        protocol.flush();

        if (isOneWay) {
            // No response will be received
            return null;
        }

        MessageMetadata metadata = protocol.readMessageBegin();

        if (metadata.seqId != sid) {
            throw new ThriftException(
                    ThriftException.Kind.BAD_SEQUENCE_ID,
                    "Unrecognized sequence ID");
        }

        if (metadata.type == TMessageType.EXCEPTION) {
            ThriftException e = ThriftException.read(protocol);
            protocol.readMessageEnd();
            throw new ServerException(e);
        } else if (metadata.type != TMessageType.REPLY) {
            throw new ThriftException(
                    ThriftException.Kind.INVALID_MESSAGE_TYPE,
                    "Invalid message type: " + metadata.type);
        }

        if (metadata.seqId != seqId.get()) {
            throw new ThriftException(
                    ThriftException.Kind.BAD_SEQUENCE_ID,
                    "Out-of-order response");
        }

        if (!metadata.name.equals(call.name)) {
            throw new ThriftException(
                    ThriftException.Kind.WRONG_METHOD_NAME,
                    "Unexpected method name in reply; expected " + call.name
                            + " but received " + metadata.name);
        }

        try {
            Object result = call.receive(protocol, metadata);
            protocol.readMessageEnd();
            return result;
        } catch (Exception e) {
            if (e instanceof Struct) {
                // Business as usual
                protocol.readMessageEnd();
            }
            throw e;
        }
    }
final Object invokeRequest(MethodCall<?> call) throws Exception {
        boolean isOneWay = call.callTypeId == TMessageType.ONEWAY;
        int sid = seqId.incrementAndGet();

        protocol.writeMessageBegin(call.name, call.callTypeId, sid);
        call.send(protocol);
        protocol.writeMessageEnd();
        protocol.flush();

        if (isOneWay) {
            // No response will be received
            return null;
        }

        MessageMetadata metadata = protocol.readMessageBegin();

        if (metadata.seqId != sid) {
            throw new ThriftException(
                    ThriftException.Kind.BAD_SEQUENCE_ID,
                    "Unrecognized sequence ID");
        }

        if (metadata.type == TMessageType.EXCEPTION) {
            ThriftException e = ThriftException.read(protocol);
            protocol.readMessageEnd();
            throw new ServerException(e);
        } else if (metadata.type != TMessageType.REPLY) {
            throw new ThriftException(
                    ThriftException.Kind.INVALID_MESSAGE_TYPE,
                    "Invalid message type: " + metadata.type);
        }

        if (metadata.seqId != seqId.get()) {
            throw new ThriftException(
                    ThriftException.Kind.BAD_SEQUENCE_ID,
                    "Out-of-order response");
        }

        if (!metadata.name.equals(call.name)) {
            throw new ThriftException(
                    ThriftException.Kind.WRONG_METHOD_NAME,
                    "Unexpected method name in reply; expected " + call.name
                            + " but received " + metadata.name);
        }

        try {
            Object result = call.receive(protocol, metadata);
            protocol.readMessageEnd();
            return result;
        } catch (Exception e) {
            if (e instanceof Struct) {
                // Business as usual
                protocol.readMessageEnd();
            }
            throw e;
        }
    }
Send the given call to the server.

@param call the remote method call to be invoked
@return the result of the method call
@throws ServerException wrapper around {@link ThriftException}. Callers should catch and unwrap this.
@throws IOException from the protocol
@throws Exception exception received from server implements {@link com.microsoft.thrifty.Struct}