0

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

从文档看来,一切都需要用 [DataContract] 装饰。在某些测试类型上使用它之后,它们确实可以正确序列化。

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

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

4

2 回答 2

2

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

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

于 2017-08-01T18:12:34.187 回答
2

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

这是我使用的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;
            }
        }
    }
于 2018-02-02T02:45:43.743 回答