服务结构远程处理序列化器

时间:2017-08-01 02:13:58

标签: serialization azure-service-fabric service-fabric-stateful

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

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

但是我坦率地说不想装饰一切。对我来说这将是一个倒退。我更喜欢一直使用自定义序列化。

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

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

随着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;
            }
        }
    }