Не удалось отправить поток protobuf через именованный канал и получить результат обратно - PullRequest
1 голос
/ 10 апреля 2019

У меня проблемы с отправкой объектов туда и обратно (двусторонняя связь) по именованным каналам. Код:

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, кажется, никогда не останавливает чтение данных из потока, поэтому я никогда не могу декодировать запрос сервера кодирования. Но если клиент принудительно остановлен, запрос будет получен.

Я также пытался использовать SteamWriter и StreamReader безрезультатно. Возможно ли передавать объекты protobuf при дуплексной связи? Буду признателен, если кто-нибудь укажет, что я делаю неправильно ..

1 Ответ

1 голос
/ 10 апреля 2019

protobuf не является самодействующим форматом данных;вам нужно использовать какое-то обрамление.К счастью, библиотека содержит несколько базовых реализаций для вашего удобства, поэтому: если вы используете SerializeWithLengthPrefix и DeserializeWithLengthPrefix (убедитесь, что используете одинаковую конфигурацию с обеих сторон): она должна работать.

Без кадрирования: природа protobuf - «читать до конца потока», то есть именно то, что вы видите.Причина этого заключается в том, что protobuf предназначен для объединения (это слово?) даже для отдельных сообщений .

...