#c# #asp.net-web-api #.net-core #asp.net-core-webapi #.net-5
Вопрос:
У меня есть веб-API .Net 5, и я хотел бы создать GET
конечную точку (действующую как подписка), отправляющую данные каждые x секунд. Я знаю, что там есть инструменты, например, SignalR, но я хотел бы знать, можно ли достичь того же результата с помощью простого маршрута. Может быть, ручей мог бы помочь …
Это мой пример контроллера
[ApiController]
[Route("[controller]")]
public class MyController : ControllerBase
{
[HttpGet]
public OkResult SendDataEvery5Seconds()
{
return Ok(); // send back an initial response
// send data every 5 seconds
}
}
Я не знаю, возможно ли это с помощью C#, но я попытался создать рабочий пример, используя узел, показывающий, чего я хочу достичь:
const express = require('express')
const app = express()
app.get('/', (req, res) => {
res.writeHead(200, {
'content-type': 'application/x-ndjson'
});
setInterval(() => {
res.write(JSON.stringify(new Date()) 'n');
}, 5000);
})
app.listen(3000);
запуск curl -i http://localhost:3000
должен записывать дату каждые 5 секунд.
Комментарии:
1. У вашего контроллера есть
Response
свойство, с помощью которого вы можете отправлять данные ответа вручную. (Response.Body
).2. Попробуйте записать цикл while с помощью thread.sleep и записать данные в ответ.
while (true) { Thread.Sleep(5000); return Ok();}
3. Это истощит ваш сервер, так как метод будет продолжать работать даже при закрытии клиента.
Ответ №1:
Вы можете сделать это вот так.
Код сервера:
[HttpGet]
public async Task Get(CancellationToken ct = default)
{
Response.StatusCode = 200;
Response.Headers["Content-Type"] = "application/x-ndjson";
// you can manage headers of the request only before this line
await Response.StartAsync(ct);
// cancellation token is important, or else your server will continue it's work after client has disconnected
while (!ct.IsCancellationRequested)
{
await Response.Body.WriteAsync(Encoding.UTF8.GetBytes("some data heren"), ct);
await Response.Body.FlushAsync(ct);
// change '5000' with whatever delay you need
await Task.Delay(5000, ct);
}
}
Соответствующий клиентский код (пример c#):
var client = new HttpClient();
var response = await client.GetStreamAsync("http://localhost:5000/");
using var responseReader = new StreamReader(response);
while (!responseReader.EndOfStream)
{
Console.WriteLine(await responseReader.ReadLineAsync());
}