未能通过命名管道发送protobuf流并返回结果

问题描述 投票:1回答:1

我在使用命名管道来回传输对象(双工通信)时遇到了麻烦。代码:

DTO:

[ProtoContract]
public class ServerResponse
{
    [ProtoMember(1)]
    public string FirstName { get; set; }

    [ProtoMember(2)]
    public string LastName { get; set; }
}

[ProtoContract]
public class ServerRequest
{
    [ProtoMember(1)]
    public string Name { get; set; }

    [ProtoMember(2)]
    public int Age { get; set; }
}

服务器:

static void Main(string[] args)
{
    Console.WriteLine("Starting Server");
    StartServer();
    Console.WriteLine("Press any key to stop server..");
    Console.ReadKey();
}

static void StartServer()
{
    Task.Factory.StartNew(() =>
    {
        var server = new NamedPipeServerStream("MyPipes");

        server.WaitForConnection();
        Console.WriteLine("Connected");

        //StreamReader reader = new StreamReader(server);
        //StreamWriter writer = new StreamWriter(server);
        while (true)
        {
            //string line = reader.ReadLine();
            //Console.WriteLine(line);
            //writer.WriteLine(line.ToUpper());
            //writer.Flush();

            var request = Serializer.Deserialize<ServerRequest>(server);
            Console.WriteLine($"Name: {request.Name}, Age: {request.Age}");

            var response = new ServerResponse() { FirstName = request.Name, LastName = "Always this name!" };
            Serializer.Serialize(server, response);
            server.Flush();
        }
    });
}

客户:

static void Main(string[] args)
{
    Console.WriteLine("Client");

    var client = new NamedPipeClientStream("MyPipes");
    client.Connect();

    //StreamReader reader = new StreamReader(client);
    //StreamWriter writer = new StreamWriter(client);
    while (true)
    {
        //string input = Console.ReadLine();
        //if (String.IsNullOrEmpty(input)) break;
        //writer.WriteLine(input);
        //writer.Flush();
        //Console.WriteLine(reader.ReadLine());

        string firstName = Console.ReadLine();
        var request = new ServerRequest() { Name = firstName, Age = firstName.Length };
        Serializer.Serialize(client, request);
        client.Flush();

        var response = Serializer.Deserialize<ServerResponse>(client);
        Console.WriteLine($"Name: {response.FirstName}, Age: {response.LastName}");
    }

    Console.WriteLine("Done");
    Console.ReadKey();
}

当发送一行string时它工作得很好,但protobuf失败了。

出于某种原因,Deserialize方法似乎永远不会停止从流中读取数据,因此我永远无法解码编码服务器请求。但是如果强制停止客户端,则会收到请求。

我也尝试使用SteamWriterStreamReader无济于事。是否有可能在双工通信中传输protobuf对象?如果有人能指出我做错了什么,我将不胜感激。

c# .net-core named-pipes protobuf-net
1个回答
1
投票

protobuf不是一种自终止数据格式;你需要使用某种框架。幸运的是,该库包含一些基本实现以方便您使用,因此:如果您使用SerializeWithLengthPrefixDeserializeWithLengthPrefix(确保在两侧使用相同的配置):它应该可以工作。

没有框架:protobuf的性质是“读到流的末尾”,即你正在看到的。这样做的原因是,即使对于单个消息,protobuf也是可以连接的(这是一个单词吗?)。

© www.soinside.com 2019 - 2024. All rights reserved.