[RRQMSocket.RPC] C# advanced usage settings of RRQMRPC based on TCP protocol

Keywords: C# JSON socket Concurrent Programming rpc

1, Preface

Notes to this section

Before learning this section, you must be familiar with the creation of TcpRpcParser parser and TcpRpcClient client (or its derived classes, such as file transfer) in RRQM. If you are not familiar with it, please understand it in the following links.

2, Assembly source code, Demo download

2.1 source location

RRQMSocket

2.2 Demo location

RRQMBox

3, Installation

Just install RRQMSocket.RPC. See the link blog for specific steps.

VS, Unity installation and use of Nuget package

4, Serialization selection

From the following figure (picture source) network )It can be seen that serialization is a crucial link in RPC. It can be said that the quality of serialization will greatly affect the performance of RPC calls.

4.1 serialization supported by rrqm

In RRQMRPC, there are four built-in serialization methods: RRQMBinary, SystemBinary, Json and Xml. The characteristics of these four methods are the characteristics of serialization.

RRQMBinarySystemBinaryJsonXml
characteristicThe serialization method has high speed and small amount of data, but the compatible data format is also limited. Only basic types, custom entity classes, arrays, lists, and dictionaries are supportedIt has high fidelity and supports serialization of interfaces, abstract classes, object s, generics and other types, but requires Serializable tags and must be of the same type (or rewrite the mapping map)Good compatibility and readability, but affected by the string, the performance is not outstanding, and the amount of data is limitedGeneral compatibility, strong readability, also affected by strings, poor performance, and limited amount of data

4.2 using preset serialization

In RRQMRPC, selecting serialization is very simple, and the serialization method is completely determined by the caller.

In the actual call, it is specified through the parameter of InvokeOption.

In fact, you only need to pass in the relevant parameters.

InvokeOption invokeOption = new InvokeOption();
invokeOption.SerializationType = RRQMCore.Serialization.SerializationType.RRQMBinary;
//invokeOption.SerializationType = RRQMCore.Serialization.SerializationType.Json;
//invokeOption.SerializationType = RRQMCore.Serialization.SerializationType.SystemBinary;
//invokeOption.SerializationType = RRQMCore.Serialization.SerializationType.Xml;

string returnString = client.Invoke<string>("TestOne", invokeOption, "10");

4.3 custom serialization

a) . definitions
To implement custom serialization, you must override the serialization selector to implement the SerializeParameter and DeserializeParameter functions. If you still want to keep the preset serialization, just press the code example.

public class MySerializationSelector: SerializationSelector
{
    /// <summary>
    ///Deserialization
    /// </summary>
    /// <param name="serializationType"></param>
    /// <param name="parameterBytes"></param>
    /// <param name="parameterType"></param>
    /// <returns></returns>
    public override object DeserializeParameter(SerializationType serializationType, byte[] parameterBytes, Type parameterType)
    {
        if (parameterBytes == null)
        {
            return parameterType.GetDefault();
        }
        switch (serializationType)
        {
            case SerializationType.RRQMBinary:
                {
                    return SerializeConvert.RRQMBinaryDeserialize(parameterBytes, 0, parameterType);
                }
            case SerializationType.SystemBinary:
                {
                    return SerializeConvert.BinaryDeserialize(parameterBytes, 0, parameterBytes.Length);
                }
            case SerializationType.Json:
                {
                    return JsonConvert.DeserializeObject(Encoding.UTF8.GetString(parameterBytes), parameterType);
                }
            case SerializationType.Xml:
                {
                    return SerializeConvert.XmlDeserializeFromBytes(parameterBytes, parameterType);
                }
            case (SerializationType)4:
                {
                    //It can be implemented here
                    return default;
                }
            default:
                throw new RRQMRPCException("Unspecified deserialization method");
        }
    }

    /// <summary>
    ///Serialization parameters
    /// </summary>
    /// <param name="serializationType"></param>
    /// <param name="parameter"></param>
    /// <returns></returns>
    public override byte[] SerializeParameter(SerializationType serializationType, object parameter)
    {
        if (parameter == null)
        {
            return null;
        }
        switch (serializationType)
        {
            case SerializationType.RRQMBinary:
                {
                    return SerializeConvert.RRQMBinarySerialize(parameter, true);
                }
            case SerializationType.SystemBinary:
                {
                    return SerializeConvert.BinarySerialize(parameter);
                }
            case SerializationType.Json:
                {
                    return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(parameter));
                }
            case SerializationType.Xml:
                {
                    return SerializeConvert.XmlSerializeToBytes(parameter);
                }
            case (SerializationType)4:
                {
                    //It can be implemented here
                    return default;
                }
            default:
                throw new RRQMRPCException("Unspecified serialization method");
        }
    }
}

b) . use

Since the assignment is an enumeration type of SerializationType, it is sufficient to perform a cast.

InvokeOption invokeOption = new InvokeOption();
invokeOption.SerializationType = (RRQMCore.Serialization.SerializationType)4;

5, Call feedback type

5.1 type description

There are three optional call states of RRQMRPC: OnlySend, WaitSend and WaitInvoke. The difference is:

OnlySendWaitSendWaitInvoke
Only sending RPC requests can ensure successful sending under the TCP underlying protocol, but it will not feed back any status of the server, and will not obtain return values, exceptions and other information. Under the UDP underlying protocol, there is no guarantee of successful sending, but only a request action.Sending an RPC request and waiting for the received status to return can ensure that the RPC request can arrive at the service smoothly, but we can't know whether the RPC service is successfully executed, and we won't get the return value, exception and other informationSend an RPC request and return all information, including whether the call was successful, the returned value or exception after execution, etc.

5.2 use

Similarly, you can directly assign values in InvokeOption.

InvokeOption invokeOption = new InvokeOption();

invokeOption.FeedbackType = FeedbackType.WaitInvoke;
//invokeOption.FeedbackType = FeedbackType.OnlySend;
//invokeOption.FeedbackType = FeedbackType.WaitSend;

string returnString = client.Invoke<string>("TestOne", invokeOption, "10");

6, Call timeout setting

When calling RPC, you cannot wait indefinitely. You must have the function of timer or task cancellation.

6.1 timer setting

You can directly assign a value to the Timeout property of InvokeOption, and the unit is milliseconds.

InvokeOption invokeOption = new InvokeOption();

invokeOption.Timeout = 1000 * 10;//If there is no response after 10 seconds, an RRQMTimeoutException exception is thrown

string returnString = client.Invoke<string>("TestOne", invokeOption, "10");

6.2 task cancellation

In RPC calls, timer is a good choice, but it is not perfect. Sometimes we want to end a call task manually. At this time, the timer can't bear the heavy task and needs the function of actively canceling the task. As everyone familiar with. net knows, CancellationToken has this function. Similarly, you only need to assign a value to the canceltoken of InvokeOption.

InvokeOption invokeOption = new InvokeOption();

CancellationTokenSource tokenSource = new CancellationTokenSource();
invokeOption.CancellationToken = tokenSource.Token;

//tokenSource.Cancel();// Cancel task on call

string returnString = client.Invoke<string>("TestOne", invokeOption, "10");

Posted by nextman on Thu, 25 Nov 2021 22:42:20 -0800