В настоящее время я создаю приложение для изучения веб-API в ASP Net Core 7. Итак, я хочу автоматически обновить 2 значения x и y с помощью веб-сокета. Вот API-контроллер котировок:
[HttpGet("ws")]
public async Task GetRealTimeQuote(int page=1,int limit = 10,string sector = "",string industry = "")
{
if (HttpContext.WebSockets.IsWebSocketRequest)
{
using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
var random = new Random();
while (webSocket.State == WebSocketState.Open)
{
int x = random.Next(1, 100);
int y = random.Next(1, 100);
var buffer = Encoding.UTF8.GetBytes($"{{ \"x\": {x}, \"y\": {y} }}");
await webSocket.SendAsync(
new ArraySegment<byte>(buffer),
WebSocketMessageType.Text, true, CancellationToken.None);
await Task.Delay(2000); //
}
}
else
{
HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
}
}
HTML-файл:
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8" />
<meta http-equiv = "X-UA-Compatible" content = "IE=edge" />
<meta name = "viewport" content = "width=device-width,initial-scale=1.0" />
<title>WebSocket Test</title>
</head>
<body>
<script>
const socket = new WebSocket(`wss://localhost:7154/api/Quote/ws`);
socket.onopen = () => {
console.info('Connected to the server via WebSocket');
};
socket.onmessage = (event) => {
const quote = JSON.parse(event.data);
console.info('Received quote:', quote);
// Update the DOM with the received quote data
document.getElementById('x-value').textContent = `X: ${quote.x}`;
document.getElementById('y-value').textContent = `Y: ${quote.y}`;
};
socket.onclose = () => {
console.info('Connection closed');
};
socket.onerror = (error) => {
console.error('WebSocket error:', error);
};
</script>
<h1>Test WebSocket, Show x, y in Real-Time</h1>
<p id = "x-value">X: </p>
<p id = "y-value">Y: </p>
</body>
</html>
В Program.cs я уже использую
var webSocketOption = new WebSocketOptions
{
KeepAliveInterval = TimeSpan.FromMinutes(2)
};
app.UseWebSockets(webSocketOption);
Проблема в том, что соединение всегда имеет ошибку. Я использовал инструмент разработчика в браузере и увидел:
Локальный хост правильный. Я до сих пор не знаю, почему соединение всегда терпит неудачу. Или это потому, что я оставил файл не в той папке. Здесь я разместил путь к html-файлу . Или я открываю его неправильно (всякий раз, когда я запускаю проект, я перехожу в папку проекта и нажимаю на файл HTML. Это приводит к тому, что файл HTML не может подключиться к WebSocket?)



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете попробовать код ниже:
ЦитатаController.cs:
using Microsoft.AspNetCore.Mvc;
using System.Net.WebSockets;
using System.Text;
namespace WebSocketExample.Controllers
{
//[ApiController]
// [Route("api/[controller]")]
public class QuoteController : ControllerBase
{
[Route("/ws")]
public async Task GetRealTimeQuote(int page = 1, int limit = 10, string sector = "", string industry = "")
{
if (HttpContext.WebSockets.IsWebSocketRequest)
{
using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
var random = new Random();
while (webSocket.State == WebSocketState.Open)
{
int x = random.Next(1, 100);
int y = random.Next(1, 100);
var buffer = Encoding.UTF8.GetBytes($"{{ \"x\": {x}, \"y\": {y} }}");
await webSocket.SendAsync(
new ArraySegment<byte>(buffer),
WebSocketMessageType.Text, true, CancellationToken.None);
await Task.Delay(2000); //
}
}
else
{
HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
}
}
}
}
Программа.cs:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowLocalhost",
builder =>
{
builder.WithOrigins("http://localhost:5130", "https://localhost:7275")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
var webSocketOptions = new WebSocketOptions
{
KeepAliveInterval = TimeSpan.FromMinutes(2),
AllowedOrigins = { "http://localhost:5130", "https://localhost:7275" }
};
app.UseCors("AllowLocalhost");
app.UseWebSockets(webSocketOptions);
app.UseStaticFiles();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
wwwroot/index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8" />
<meta http-equiv = "X-UA-Compatible" content = "IE=edge" />
<meta name = "viewport" content = "width=device-width,initial-scale=1.0" />
<title>WebSocket Test</title>
</head>
<body>
<script>
const socket = new WebSocket('wss://localhost:7275/ws');
socket.onopen = () => {
console.info('Connected to the server via WebSocket');
};
socket.onmessage = (event) => {
const quote = JSON.parse(event.data);
console.info('Received quote:', quote);
document.getElementById('x-value').textContent = `X: ${quote.x}`;
document.getElementById('y-value').textContent = `Y: ${quote.y}`;
};
socket.onclose = (event) => {
console.info('Connection closed', event);
};
socket.onerror = (error) => {
console.error('WebSocket error:', error);
};
</script>
<h1>Test WebSocket, Show x, y in Real-Time</h1>
<p id = "x-value">X: </p>
<p id = "y-value">Y: </p>
</body>
</html>
проверьте этот официальный образец:
запуск html-файла с использованием протокола
file://может вызвать проблемы с соединениями WebSocket. попробуйте запустить html-файл, используя localhost: YOUR_PORT. если вы пытаетесь получить доступ к приложению из другого источника, убедитесь, что вы добавили код Cors. попробуйте переместить html-файл в папку wwwroot. попробуйте получить доступ к URL-адресу webscoket с помощьюws://.