跳到主要内容
版本:1.3.9

序列化选择器

一、说明

从下图(图片来源网络)可以看出,序列化是RPC中至关重要的一个环节,可以说,序列化的优劣,会很大程度的影响RPC调用性能。

二、支持的序列化

在TouchRpc中,内置了四种序列化方式,分别为FastBinaryJsonXmlSystemBinary。这四种方式的特点,就是其序列化的特点。

FastBinaryJsonXmlSystemBinary
特点序列化方式速度快,数据量小,但是兼容的数据格式也比较有限。仅支持基础类型、自定义实体类、数组、List、字典兼容性好,可读性强,但是受字符串影响,性能不出众,且数据量受限制兼容性一般,可读性强,同样受字符串影响,性能不出众,且数据量受限制序列化速度快。但是兼容性低。且要求类必须一致,不然需要重新指定图根。

三、使用预设序列化

在TouchRpc中,选择序列化是非常简单的,且序列化方式完全由调用端决定。 在实际的调用中,通过InvokeOption的参数指定。

实际上,只需要传入相关参数即可。

InvokeOption invokeOption = new InvokeOption() //InvokeOption是结构体,所以成员必须全部初始化。
{
FeedbackType = FeedbackType.WaitInvoke,
Timeout = 1000 * 10
};
;
invokeOption.SerializationType = SerializationType.FastBinary;
//invokeOption.SerializationType = Serialization.SerializationType.Json;
//invokeOption.SerializationType = Serialization.SerializationType.Xml;
string returnString = client.Invoke<string>("TestOne", invokeOption, "10");

四、自定义序列化

4.1 定义自定义序列化器

想要实现自定义序列化,必须通过重写序列化选择器,实现SerializeParameterDeserializeParameter函数。

下列代码将以MemoryPack序列化作为示例,并且保留了预设序列化。

public class MemoryPackSerializationSelector:DefaultSerializationSelector
{
public override byte[] SerializeParameter(SerializationType serializationType, object parameter)
{
if ((byte)serializationType == 4)
{
return MemoryPackSerializer.Serialize(parameter.GetType(),parameter);
}
return base.SerializeParameter(serializationType, parameter);
}

public override object DeserializeParameter(SerializationType serializationType, byte[] parameterBytes, Type parameterType)
{
if ((byte)serializationType == 4)
{
if (parameterBytes==null)
{
return default;
}
return MemoryPackSerializer.Deserialize(parameterType,parameterBytes);
}
return base.DeserializeParameter(serializationType, parameterBytes, parameterType);
}
}

4.2 使用

必须在服务器客户端Config配置中设置解析器。

var config = new TouchSocketConfig()//配置
.SetSerializationSelector(new MemoryPackSerializationSelector());

然后,因为赋值时是SerializationType的枚举类型,所以执行强制类型转换即可。

InvokeOption invokeOption = new InvokeOption()
{
FeedbackType = FeedbackType.WaitInvoke,
SerializationType = (SerializationType)4,
Timeout = 1000 * 10
};

var msg = client.Login(new LoginModel() { Account = "Account", Password = "Password" }, invokeOption);
提示

因为使用的是MemoryPack序列化,所以最好将Rpc的所有参数声明在单独的程序集中。这样客户端与服务器项目都可以直接引用。

序列化选择器示例代码