Я пытаюсь настроить IPC с помощью именованных труб. Мне нужно передавать данные из одного сервера/менеджера в стиле Windows на различные клиенты. Процедура запроса-ответа довольно проста, поэтому у меня есть одна модель для каждой из них. Я планирую, что сервер/управляющий хост будет несколько именованных трубных серверов. Когда клиент должен общаться, он создаст трубного клиента, подключите, сериализует модель запроса в качестве JSON и отправит ее через трубу. Сервер/менеджер сериализует модель ответа и отправит ее обратно, затем отключите и начнете ждать нового соединения.NamedPipeServerStream или and andpipeclientstream ). Я не уверен, что я делаю не так, так как могу преобразовать модель в JSON и отправить ее с помощью буфера просто отлично, но я бы предпочел сериализовать непосредственно на поток. < /P>
Вот упрощенная версия кода.using System;
using System.IO.Pipes;
using System.Text.Json;
using System.Threading.Tasks;
namespace NamedPipeDemo.Client
{
public class Program
{
public static async Task Main(string[] args)
{
while (true)
{
await using var client = new NamedPipeClientStream("PSSharp/NamedPipeDemo");
await client.ConnectAsync();
Console.Write("Enter message body for server: ");
var message = Console.ReadLine();
var request = new Request()
{
Content = message
};
Console.WriteLine("{0}: Sending data.", DateTime.Now);
await JsonSerializer.SerializeAsync(client, request);
await client.FlushAsync();
Console.WriteLine("{0}: Data written to pipe.", DateTime.Now);
var response = await JsonSerializer.DeserializeAsync(client);
Console.WriteLine("{0}: Response received from server.\n{1}", DateTime.Now, JsonSerializer.Serialize(response));
if (response is null)
{
break;
}
}
}
}
}
< /code>
Сервер < /p>
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO.Pipes;
using System.Linq;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
namespace NamedPipeDemo.Server
{
public class Worker : BackgroundService
{
private readonly ILogger _logger;
public Worker(ILogger logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await using var server = new NamedPipeServerStream("PSSharp/NamedPipeDemo", PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous | PipeOptions.WriteThrough);
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("{time} : Waiting for client to connect.", DateTime.Now);
await server.WaitForConnectionAsync(stoppingToken);
_logger.LogInformation("{time} : Client with identity (unknown) connected.", DateTime.Now);
// this call never returns
var request = await JsonSerializer.DeserializeAsync(server, null, stoppingToken);
var response = await GetResponseAsync(request, stoppingToken);
await JsonSerializer.SerializeAsync(server, response, null, stoppingToken);
_logger.LogInformation("{time} : Communication with client terminated. Waiting for new client.", DateTime.Now);
server.Disconnect();
}
}
protected virtual async ValueTask GetResponseAsync(Request? request, CancellationToken cancellation)
{
if (request?.Content?.Contains("wait") ?? false)
{
_logger.LogInformation("Stimulating work.");
await Task.Delay(1000, cancellation);
}
if (request?.Content?.Contains("exit") ?? false)
{
return null;
}
var shouldEcho = request?.Content?.Contains("echo") ?? false;
var echoContent = shouldEcho ? request?.Content : "The message was processed.";
var error = default(string);
if (echoContent is null)
{
echoContent = "No content to echo.";
error = "No content to echo.";
}
var response = new Response(echoContent, error);
return response;
}
}
}
< /code>
Модели < /p>
using System;
using System.Text.Json.Serialization;
namespace NamedPipeDemo
{
public class Request
{
private static int s_id;
public int Id { get; private set; } = ++s_id;
public string? Content { get; set; }
}
public class Response
{
private static int s_id;
[JsonConstructor]
private Response(int id,string? error, string message)
{
Id = id;
Error = error;
Message = message;
}
public Response(string message, string? error = null)
{
Message = message;
Error = error;
}
public int Id { get; } = ++s_id;
public string? Error { get; }
public string Message { get; }
}
}
Подробнее здесь: https://stackoverflow.com/questions/687 ... pipestream
Jsonserializer.serializeasync/deserializeasync вешает на Pipestream ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Asyncio Async Funcitons вешает с Asyncio.gather. (Код работает без Asyncio.gather)
Anonymous » » в форуме Python - 0 Ответы
- 22 Просмотры
-
Последнее сообщение Anonymous
-