服务结构远程序列化程序

Service fabric remoting serializer

在试验 Service Fabric 远程处理时,我有一些数据类型没有正确序列化。这给我带来了很多问题。

从文档来看,似乎所有内容都需要用 [DataContract] 修饰。在某些测试类型上使用它之后,它们似乎确实序列化正确。

但是坦率地说,我不想装饰所有东西。这对我来说是一个巨大的倒退。我宁愿一直使用自定义序列化。

documentation 似乎表明可以注册自定义序列化程序,但它似乎仅适用于有状态服务。我主要使用带有无状态服务的远程处理。

当前的远程处理堆栈要求您的类型使用 DataContract。据推测,该团队即将在不久的将来发布一个新的远程处理堆栈,其中包含插入自定义序列化的能力以及性能方面的许多改进,但这还不可用。

与此同时,一种解决方法(您认为这不是一个很好的方法)是让您的所有代理接收 stringbyte[] 或类似的东西并处理 serialization/deserialization 手动使用 JSON.Net 之类的东西。就我个人而言,我会咬紧牙关,让您的类型数据契约可序列化,直到新的远程处理位可用。

随着 Service Fabric V2 Remoting 的发布,现在这成为可能。有关详细信息,请参阅 here。以下

这是我使用过的 MessagePack 远程序列化程序的一个实现,但在您的情况下,文档中的 JSON 示例可能就足够了。

    public class MessagePackMessageFactory : IServiceRemotingMessageBodyFactory
    {
        public IServiceRemotingRequestMessageBody CreateRequest(string interfaceName, string methodName, int numberOfParameters)
        {
            return new MessagePackRemotingRequestMessageBody(numberOfParameters);
        }

        public IServiceRemotingResponseMessageBody CreateResponse(string interfaceName, string methodName)
        {
            return new MessagePackServiceRemotingResponseMessageBody();
        }
    }


 [MessagePackObject]
  public class MessagePackRemotingRequestMessageBody : IServiceRemotingRequestMessageBody
  {
    [Key(0)]
    public object Value;

    public MessagePackRemotingRequestMessageBody()
    {
    }

    public MessagePackRemotingRequestMessageBody(int parameterInfos)
    {

    }

    public void SetParameter(int position, string paramName, object parameter)
    {
      Value = parameter;
    }

    public object GetParameter(int position, string paramName, Type paramType)
    {
      return Value;
    }
  }

 [MessagePackObject]
  public class MessagePackServiceRemotingResponseMessageBody : IServiceRemotingResponseMessageBody
  {
    [Key(0)]
    public object Response;

    public object Get(Type paramType)
    {
      // ignore paramType?
      return Response;
    }

    public void Set(object response)
    {
      Response = response;
    }
  }

 public class ServiceRemotingResponseMessagePackMessageBodySerializer : IServiceRemotingResponseMessageBodySerializer
    {
        public OutgoingMessageBody Serialize(IServiceRemotingResponseMessageBody responseMessageBody)
        {
            if (!(responseMessageBody is MessagePackServiceRemotingResponseMessageBody body))
            {
                return new OutgoingMessageBody(new[] { new ArraySegment<byte>(new byte[0]) });
            }

            var bytes = MessagePackSerializer.Serialize(body, ServiceFabricResolver.Instance);

            return new OutgoingMessageBody(new[] { new ArraySegment<byte>(bytes) });
        }

        public IServiceRemotingResponseMessageBody Deserialize(IncomingMessageBody messageBody)
        {
            using (var stream = messageBody.GetReceivedBuffer())
            {
                if (stream.Length == 0)
                {
                    return new MessagePackServiceRemotingResponseMessageBody();
                }

                var body = MessagePackSerializer.Deserialize<MessagePackServiceRemotingResponseMessageBody>(stream, ServiceFabricResolver.Instance);
                return body;
            }
        }
    }

 public class ServiceRemotingMessagePackSerializationProvider : IServiceRemotingMessageSerializationProvider
  {
    public IServiceRemotingRequestMessageBodySerializer CreateRequestMessageSerializer(Type serviceInterfaceType,
      IEnumerable<Type> requestBodyTypes)
    {
      return new ServiceRemotingRequestMessagePackMessageBodySerializer();
    }

    public IServiceRemotingResponseMessageBodySerializer CreateResponseMessageSerializer(Type serviceInterfaceType, IEnumerable<Type> responseBodyTypes)
    {
      return new ServiceRemotingResponseMessagePackMessageBodySerializer();
    }

    public IServiceRemotingMessageBodyFactory CreateMessageBodyFactory()
    {
      return new MessagePackMessageFactory();
    }
  }

 public class ServiceRemotingRequestMessagePackMessageBodySerializer : IServiceRemotingRequestMessageBodySerializer
    {
        public OutgoingMessageBody Serialize(IServiceRemotingRequestMessageBody serviceRemotingRequestMessageBody)
        {
            if (serviceRemotingRequestMessageBody == null) return null;

            if (!(serviceRemotingRequestMessageBody is MessagePackRemotingRequestMessageBody body))
            {
                return new OutgoingMessageBody(new[] { new ArraySegment<byte>(new byte[0]) });
            }

            var bytes = MessagePackSerializer.Serialize(body, ServiceFabricResolver.Instance);

            return new OutgoingMessageBody(new[] { new ArraySegment<byte>(bytes) });
        }

        public IServiceRemotingRequestMessageBody Deserialize(IncomingMessageBody messageBody)
        {
            using (var stream = messageBody.GetReceivedBuffer())
            {
                if (stream.Length == 0)
                {
                    return new MessagePackRemotingRequestMessageBody();
                }

                var body = MessagePackSerializer.Deserialize<MessagePackRemotingRequestMessageBody>(stream, ServiceFabricResolver.Instance);
                return body;
            }
        }
    }