0

在尝试使用Service Fabric远程处理时,我有一些数据类型未正确序列化。这导致我很多问题。服务结构远程处理串行器

从文档看来,所有东西都需要用[DataContract]进行修饰。在某些测试类型上使用它之后,它确实显示它们序列化正确。

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

这个documentation似乎表明它可以注册一个自定义序列化器,但它似乎只用于有状态服务。我主要使用无状态服务进行远程处理。

+0

'从文档看来,一切都需要使用[DataContract] .'装饰,你不必 – Mardoxx

+0

这是真的。 [DataContract]会尝试将其可能的序列化。但是无法序列化的东西需要明确的帮助。 – Telavian

回答

2

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

与此同时,解决方法是让所有的代理服务器都得到stringbyte[]或类似的东西,并使用类似JSON.Net的方式手动处理序列化/反序列化。就我个人而言,我会咬紧牙关,让你的类型Data Contract Serializable直到新的远程位可用。

+0

感谢您的信息。这目前听起来像是最好的方法。 – Telavian

0

随着Service Fabric V2 Remoting的发布,现在可以实现了。有关更多详细信息,请参阅here

这里是我使用过的远程处理序列化程序的一个实现,但在你的情况下,文档中的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; 
      } 
     } 
    }