C# 通过 http 传输序列化 Protobuf 数据的最佳方式

标签 c# .net protobuf-net data-transfer-objects

我正在使用 Marc Gravell 的 Protobub-Net序列化和反序列化对象。

我正在寻找通过 http:// 请求传输数据的最有效方式。

这是我到目前为止所做的:

public string ProtobuffToString()
{
    Dictionary<int, decimal> List1 = new Dictionary<int, decimal>();
    List1.Add(2018, 1.2m);
    List1.Add(2017, 1.4m);
    List1.Add(2016, 1.9m);

    using (var stream = new MemoryStream())
    {
         ProtoBuf.Serializer.Serialize(stream, List1);
        return Convert.ToBase64String(stream.ToArray());
    }
}

public async System.Threading.Tasks.Task<string> ReadProtobuffAsync()
{
    using (System.Net.Http.HttpClient client = new System.Net.Http.HttpClient())
    using (System.Net.Http.HttpResponseMessage response = await client.GetAsync("http://localhost:53204/ProtobuffToString")) //<= Will call ProtobuffToString() above
    using (System.Net.Http.HttpContent content = response.Content)
    {
        string result = await content.ReadAsStringAsync();
        byte[] resultByte = Convert.FromBase64String(result);

        using (var stream = new MemoryStream(resultByte))
        {
            return JsonConvert.SerializeObject(ProtoBuf.Serializer.Deserialize<Dictionary<int, decimal>>(stream));
        }
    }
}

我可以做得更好吗?

它比从 json/Json.Net 传输更好/更快吗?

也许是的,因为数据传输会更小,序列化/反序列化更快。

最佳答案

Can i do it better?

Protobuf 是一种二进制序列化格式,针对(反)序列化和低占用空间传输进行了优化。通过将数据转换为 Base64,您可以添加另一个转换层并增加传输的占用空间。

And is it better/faster than to transfer it from json/Json.Net?

没有合理的论据可以支持这一说法。重申我之前的声明,Protobuf 是高度优化的,而 JSON 是某种权衡,序列化效率不高,可读性也不是很好。

话虽如此,举个小例子,如何通过 HTTP 发送你的 Protobuf

HttpClient client = new HttpClient();
using (var stream = new MemoryStream())
{
    // serialize to stream
    ProtoBuf.Serializer.Serialize(stream, List1);
    stream.Seek(0, SeekOrigin.Begin);

    // send data via HTTP
    StreamContent streamContent = new StreamContent(stream);
    streamContent.Headers.Add("Content-Type", "application/octet-stream");
    var response = client.PostAsync("http://what.ever/api/upload", streamContent);
}

如果您想接收 Protobuf,您可以像这样修改您的代码段

using (System.Net.Http.HttpClient client = new System.Net.Http.HttpClient())
using (System.Net.Http.HttpResponseMessage response = await client.GetAsync("http://localhost:53204/ProtobuffToString")) //<= Will call ProtobuffToString() above
using (System.Net.Http.HttpContent content = response.Content)
using (var memoryStream = new MemoryStream())
{
    await content.CopyToAsync(memoryStream);
    memoryStream.Seek(0, SeekOrigin.Begin); // reset stream

    return ProtoBuf.Serializer.Deserialize<Dictionary<int, decimal>>(memoryStream); // assuming that you return the Dictionary, not a string
}

其实我不明白你为什么要返回 string而不是 Dictionary<int, decimal>来自 ReadProtobuffAsync .我建议删除 Dictionary完全使用有意义的 protobuf 定义和相应的类,因为这是 Protobuf 的真正强项。

关于C# 通过 http 传输序列化 Protobuf 数据的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48948216/

相关文章:

c# - 在我的 d-link 打印服务器上查询打印机状态

c# - 如何从数组中获取所有可能的组合?

protobuf-net - 自定义模型的部分序列化

c# - Protobuf-net序列化byte[]数据,每个字节前加 '00'

c# - C# 解决方案可以有多种形式,但在编译时选择一种作为主要形式吗?

c# - 我可以将字符串转换为 C# 中的资源位置吗?

c# - 为什么 .Net Framework 的加密如此复杂?

.net - 您遇到的最令人印象深刻的 LINQ 语句是什么?

c# - 如何使用 ProtoGen 从 proto 文件生成结构

c# - Azure函数无法读取应用程序设置和连接字符串