Как в asp net core отображать ответы gRPC стрима с использованием HTML разметки?

У меня обычно используется REST API, где я получаю ответ от API через JavaScript и затем изменяю разметку, вставляя этот ответ. Однако, я хотел бы узнать, как это сделать с gRPC?

В следующем коде в цикле foreach я получаю этот поток данных, и как мне вставить эти элементы в HTML?

Код контроллера:
```csharp
public HomeController()
{
    ChatRun();
}

private async Task ChatRun()
{
    var _messages = new List<string>();
    var channel = GrpcChannel.ForAddress("https://localhost:7151");

    var client = new Messager.MessagerClient(channel);

    var stream = Task.Run(() => client.Send(new Request() { Message = "1" }));

    await foreach (var item in (await stream).ResponseStream.ReadAllAsync())
    {
        // Как я могу передать item в HTML?
    }
}
```
  • 1 октября 2023 г. 17:37
Ответы на вопрос 2
В asp.net core вы можете использовать SignalR для обновления HTML в режиме реального времени. SignalR позволяет установить постоянное соединение между клиентом и сервером, чтобы обновления отображались мгновенно.

Вам понадобится добавить пакеты NuGet: `Microsoft.AspNetCore.SignalR`, `Microsoft.AspNetCore.SignalR.Protocols.MessagePack` и `Microsoft.AspNetCore.SignalR.Protocols.Json`. Затем, добавьте класс Hub, который будет служить веб-хабом для взаимодействия с клиентом. Например:

```csharp
using Microsoft.AspNetCore.SignalR;

namespace YourProjectNamespace
{
    public class ChatHub : Hub
    {
    }
}
```

Затем, добавьте сервис SignalR в `Startup.cs` в методе `ConfigureServices`:

```csharp
services.AddSignalR();
```

Теперь, в вашем контроллере, вы можете вести обновление HTML через SignalR. Добавьте экземпляр `IHubContext<ChatHub>` в контроллер через внедрение зависимостей:

```csharp
private readonly IHubContext<ChatHub> _hubContext;

public HomeController(IHubContext<ChatHub> hubContext)
{
    _hubContext = hubContext;
    ChatRun();
}
```

Используйте метод `Clients.All.SendAsync` для отправки сообщений на всех подключенных клиентов SignalR. В вашем случае, вставьте ответы gRPC в HTML при помощи SignalR:

```csharp
await _hubContext.Clients.All.SendAsync("ReceiveMessage", item);
```

На стороне клиента (JavaScript), подключитесь к SignalR и слушайте сообщения, чтобы вставлять их в HTML:

```javascript
var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();

connection.on("ReceiveMessage", function (message) {
    // вставьте элементы в ваш HTML
});

connection.start().then(function () {
    // подключение успешно установлено
}).catch(function (error) {
    // ошибка подключения
});
```

Добавьте соответствующий маршрут в `Startup.cs`, чтобы SignalR мог обрабатывать запросы клиентов:

```csharp
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");

    endpoints.MapHub<ChatHub>("/chatHub");
});
```

Теперь, как только у вас есть новые элементы для отображения, вы можете использовать SignalR для отправки этих элементов на клиентскую сторону, где они могут быть вставлены в HTML.
Вставка элементов в HTML в реальном времени невозможна. Однако у тебя есть два варианта решения этой задачи: 

1. Если стрим ограниченный, то ты можешь собрать все элементы в список и вернуть его обычным способом.

2. Использование веб-сокетов - для этого нужно подробнее продумать, как это будет работать с существующей архитектурой. Как минимум, тебе понадобится добавить JavaScript на фронтенде и создать долгоживущую задачу на бэкенде.

Похожие вопросы