序列化选择器
一、说明
从下图(图片来源网络)可以看出,序列化是RPC中至关重要的一个环节,可以说,序列化的优劣,会很大程度的影响RPC调用性能。
二、支持的序列化
在TouchRpc中,内置了四种序列化方式,分别为FastBinary
、Json
、Xml
、SystemBinary
。这四种方式的特点,就是其序列化的特点。
FastBinary | Json | Xml | SystemBinary | |
---|---|---|---|---|
特点 | 序列化方式速度快,数据量小,但是兼容的数据格式也比较有限。仅支持基础类型、自定义实体类、数组、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 定义自定义序列化器
想要实现自定义序列化,必须通过重写序列化选择器,实现SerializeParameter
和DeserializeParameter
函数。
下列代码将以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的所有参数声明在单独的程序集中。这样客户端与服务器项目都可以直接引用。