Именованные каналы не работают для асинхронной дуплексной связи

Почему-то я не могу заставить именованные каналы работать для дуплексной связи между клиентом и сервером для приложения .Net. Дуплексная связь работает нормально, когда я перехожу к последовательному обмену сообщениями, но когда я делаю это случайным, т. Е. Сервер и клиент могут пинговать друг друга в любое случайное время, это просто не работает.

Другие сообщения также не очень полезны - c# Full Duplex Asynchronous Named Pipes. НЕТТО

Я прилагаю свой код, как показано ниже:

-Код сервера:

        namespace Server
        {
            class Program
            {
                static void Main(string[] args)
                {
                    var namedPipeServerStream = new NamedPipeServerStream("myPipe",
                        PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous);
                    Task.Run(() => StartListeningAsync(namedPipeServerStream, (msg) => Console.WriteLine(msg)));
                    Task.Run(() => SendMessageAsync(namedPipeServerStream));
                    Console.ReadLine();
                }

                public static async Task SendMessageAsync(NamedPipeServerStream namedPipeServer)
                {
                    using (var stream = new StreamWriter(namedPipeServer))
                    {
                        while (true)
                        {
                            await Task.Delay(2000);
                            try
                            {
                                var serialized = JsonConvert.SerializeObject($"Server {DateTime.Now}");
                                byte[] messageBytes = Encoding.UTF8.GetBytes(serialized);
                                if (!namedPipeServer.IsConnected)
                                {
                                    namedPipeServer.WaitForConnection();
                                    Console.WriteLine("Client connected");
                                }
                                await namedPipeServer.WriteAsync(messageBytes, 0, messageBytes.Length);
                                await namedPipeServer.FlushAsync();
                                namedPipeServer.WaitForPipeDrain();
                            }
                            catch (Exception exception)
                            {
                                Console.WriteLine($"Exception:{exception}");
                            }
                        }
                    }
                }

                public static async Task StartListeningAsync(NamedPipeServerStream namedPipeServer, Action<string> messageRecieved)
                {
                    while (true)
                    {
                        try
                        {

                            StringBuilder messageBuilder = new StringBuilder();
                            string messageChunk = string.Empty;
                            byte[] messageBuffer = new byte[1024];
                            do
                            {
                                if (!namedPipeServer.IsConnected)
                                {
                                    namedPipeServer.WaitForConnection();
                                    Console.WriteLine("Client connected");
                                }
                                await namedPipeServer.ReadAsync(messageBuffer, 0, messageBuffer.Length);
                                messageChunk = Encoding.UTF8.GetString(messageBuffer);
                                messageBuilder.Append(messageChunk);
                                messageBuffer = new byte[messageBuffer.Length];
                            } while (!namedPipeServer.IsMessageComplete);
                            if (messageRecieved != null)
                            {
                                messageRecieved(JsonConvert.DeserializeObject<string>(messageBuilder.ToString()));
                            }
                        }
                        catch (Exception exception)
                        {
                            Console.WriteLine($"Exception:{exception}");
                        }
                    }
                }   
            }
        }

Код клиента:

            namespace Client
            {
                class Program
                {
                    static void Main(string[] args)
                    {
                        var namedPipeClientStream = new NamedPipeClientStream(".", "server", PipeDirection.InOut, PipeOptions.Asynchronous,
                                            TokenImpersonationLevel.Impersonation);
                        Task.Run(() => StartListeningAsync(namedPipeClientStream, (msg) => Console.WriteLine(msg)));
                        Task.Run(() => SendMessageAsync(namedPipeClientStream));
                        Console.ReadLine();
                    }

                    public static async Task SendMessageAsync(NamedPipeClientStream namedPipeClient)
                    {
                        using (var stream = new StreamWriter(namedPipeClient))
                        {
                            while (true)
                            {
                                try
                                {
                                    await Task.Delay(3000);
                                    var serialized = JsonConvert.SerializeObject($"Client {DateTime.Now}");
                                    byte[] messageBytes = Encoding.UTF8.GetBytes(serialized);
                                    if (!namedPipeClient.IsConnected)
                                    {
                                        namedPipeClient.Connect();
                                        namedPipeClient.ReadMode = PipeTransmissionMode.Message;
                                        Console.WriteLine("Client connected");
                                    }
                                    await namedPipeClient.WriteAsync(messageBytes, 0, messageBytes.Length);
                                    await namedPipeClient.FlushAsync();
                                    namedPipeClient.WaitForPipeDrain();
                                }
                                catch (Exception exception)
                                {
                                    Console.WriteLine($"Exception:{exception}");
                                }
                            }
                        }
                    }

                    public static async Task StartListeningAsync(NamedPipeClientStream namedPipeClient, Action<string> messageRecieved)
                    {
                        using (var streamReader = new StreamReader(namedPipeClient))
                        {
                            while (true)
                            {
                                try
                                {

                                    StringBuilder messageBuilder = new StringBuilder();
                                    string messageChunk = string.Empty;
                                    byte[] messageBuffer = new byte[1024];
                                    do
                                    {
                                        if (!namedPipeClient.IsConnected)
                                        {
                                            namedPipeClient.Connect();
                                            namedPipeClient.ReadMode = PipeTransmissionMode.Message;
                                        }
                                        await namedPipeClient.ReadAsync(messageBuffer, 0, messageBuffer.Length);
                                        messageChunk = Encoding.UTF8.GetString(messageBuffer);
                                        messageBuilder.Append(messageChunk);
                                        messageBuffer = new byte[messageBuffer.Length];
                                    } while (!namedPipeClient.IsMessageComplete);
                                    if (messageRecieved != null)
                                    {
                                        messageRecieved(JsonConvert.DeserializeObject<string>(messageBuilder.ToString()));
                                    }
                                }
                                catch (Exception exception)
                                {
                                    Console.WriteLine($"Exception:{exception}");
                                }
                            }
                        }
                    }
                }
            }

person Subasish    schedule 16.06.2018    source источник
comment
Разве named pipes не используется для связи между процессами на одной машине?   -  person Legends    schedule 16.06.2018
comment
@Legends Это также могут быть разные машины в одной локальной сети. Первый параметр конструктора NamedPipeClientStream указывает машину, а . — локальную машину.   -  person ckuri    schedule 16.06.2018
comment
@ckuri Ты прав. читать здесь Именованный канал имеет имя и может использоваться для односторонней или дуплексной связи между процессами на одной машине. и: Транспорт именованного канала имеет очень малую досягаемость; он может подключаться только к службам, работающим на одном компьютере. и: Именованные каналы могут использоваться для обеспечения связи между процессами на одном компьютере или между процессами на разных компьютерах в сети.   -  person Legends    schedule 16.06.2018
comment
Дополнение: Если служба сервера запущена, все именованные каналы доступны удаленно   -  person Legends    schedule 16.06.2018
comment
@Legends Ваша ссылка предназначена для WCF, поэтому может случиться так, что они ограничены локальным компьютером в WCF. К обычным именованным каналам можно получить доступ с других компьютеров, см. Именованные каналы можно использовать для межпроцессного взаимодействия локально или по сети. и Имя удаленного компьютера, к которому необходимо подключиться, или . чтобы указать локальный компьютер.   -  person ckuri    schedule 16.06.2018
comment
Я их читал, раньше думал, что это только для общения на одном компе, но можно и по локальной сети... Named pipes это часть WCF   -  person Legends    schedule 16.06.2018
comment
К сожалению, наши комментарии не отвечают на его проблему ;-)   -  person Legends    schedule 16.06.2018
comment
Извините, ребята ... мой плохой ... Я должен был четко указать, что оба процесса работают на одной машине. Для моего же блага я только что сделал это демонстрационное приложение для имитации дуплексной связи с использованием именованных каналов на одном компьютере, предпочитая вызывать один клиент, а другой сервер :)   -  person Subasish    schedule 18.06.2018