2010-08-09 10 views
3

Je cherche un moyen d'ajouter une valeur sérialisée d'un objet (octet []) à un champ répété dans un tampon de protocole message.Ajouter une valeur sérialisée brute à un champ répété dans les tampons de protocole (protobuf-net, protobuf-csharp)

J'ai une application qui conserve les éléments de données sous forme sérialisée dans memcached et doit les livrer aux clients distants. Le client demande des éléments de données en fournissant une liste de clés et le serveur renvoie la liste des éléments de données. Le contenu des éléments de données n'est pas important pour le serveur; il n'a pas besoin de savoir ce qu'il contient, il n'a besoin que de connaître sa clé. L'approche actuelle consiste à récupérer les éléments de memcached, à les désérialiser, à les ajouter à la liste des éléments de données dans une réponse, à sérialiser la réponse dans un tableau d'octets et à l'envoyer sur un socket. Ce n'est pas optimal, car nous désérialisons les éléments de données uniquement pour les remettre en série à l'étape suivante. Les deux sérialisations (pour memcached et pour la sortie) sont effectuées avec des tampons de protocole. Idéalement, nous pourrions ignorer la désérialisation après avoir extrait les données de memcached et ajouté les valeurs sérialisées à la réponse. J'ai regardé à la fois protobuf-net et protobuf-csharp et n'a pas trouvé un moyen d'accomplir cela. C'est possible? Ai-je oublié quelque chose?

Voici les définitions proto (simplifié):

message Request {  
    required int32 messageId; 
    repeated string keys; 
} 

message DataItem { 

    required string key = 1; 
    required ValueType type = 2;  // the type of the value, enumeration 

    optional int32 intValue = 3; 
    optional int64 longValue = 4; 
    optional double doubleValue = 5; 
    optional float floatValue = 6; 
    optional bool boolValue = 7; 
    optional string stringValue = 8; 
} 

message Response { 
    required int32 messageId; 
    repeated DataItem dataItems; 
} 

Répondre

1

Eh bien, le type de champ bytes représente des données binaires opaque ... est-ce que vous cherchez? Notez qu'à des fins d'immutabilité (dans protobuf-csharp de toute façon), elles sont représentées comme des valeurs immuables ByteString - mais vous pourrez les copier d'un message à un autre sans copier les données réelles (par exemple, garder une seule référence au même blob dans deux messages).

+0

Dans ce cas, je devrais remplacer DataItem dans le message de réponse par 'bytes' et laisser au client d'interpréter ces octets comme des objets DataItem. Je cherchais une solution qui garderait la sécurité de type et permette toujours l'ajout d'objets sous forme sérialisée (binaire). –

+0

@Boris: Je ne crois pas avoir vu un moyen de le faire dans une bibliothèque protobuf. –

+0

Eh bien, je suppose que c'était trop beau pour être vrai;) Merci pour votre réponse rapide Jon! –

0

Vous pouvez ajouter un message à votre protobuf:

message RawResponse { 
    required int32 messageId; 
    repeated bytes dataItems; 
} 

Alors, ne suit:

  1. Fetch articles memcached directement dans RawResponse
  2. Envoyer RawResponse retour
  3. Sur le client désérialiser en réponse

Cette approche fonctionnera car RawResponse et Response auront la même représentation binaire. [1]