????????在 Web 開發中,后端存在一些值得注意的通信協議,用于將更改通知給已連接的客戶端。所有這些協議都用于處理同一件事。但鮮為人知的協議很少,鮮為人知的協議也很少。今天,將討論 WebSocket,它在開發中使用最少,但它速度很快,是所有協議的根源!它通過單個持久連接在客戶端和服務器之間進行全雙工雙向通信。這與傳統的 HTTP 協議形成了鮮明對比,因為傳統的 HTTP 協議每個請求-響應周期都需要建立新的連接。WebSocket 非常適合實時應用程序,因為它們允許服務器將數據推送到客戶端,而無需等待客戶端請求。
????????將使用 .NET Core Web API 應用程序進行演示。希望大家知道如何使用 Visual Studio 創建 .NET Core Web API 應用程序。因此,不會從頭開始演示,而是重點介紹如何在現有應用程序中使用它,并在發生任何更改后通知連接的客戶端。
1. 將 WebSocket 添加到應用程序
修改您的Program.cs以啟用 WebSockets。
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseWebSockets();
app.UseRouting();
app.MapControllers();
app.Run();
2.創建WebSocket服務
創建服務和接口來管理 WebSocket 連接。
namespace GraphicsBackend.Services
{
public interface IWebSocketService
{
Task AddSocketAsync(WebSocket webSocket);
Task BroadcastAsync(SocketMessage message);
Task NotifyClientsAsync(string message);
}
}
namespace GraphicsBackend.Services
{
? ? public class WebSocketService : IWebSocketService
{
private static readonly List<WebSocket> _connections = new();
public async Task AddSocketAsync(WebSocket webSocket)
{
_connections.Add(webSocket);
var buffer = new byte[1024 * 4];
while (webSocket.State == WebSocketState.Open)
{
var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
if (result.MessageType == WebSocketMessageType.Close)
{
_connections.Remove(webSocket);
await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closed by client", CancellationToken.None);
}
}
? ? ? ? }
public async Task NotifyClientsAsync(string message)
{
var tasks = _connections
.Where(s => s != null && s.State == WebSocketState.Open)
.Select(s => s.SendAsync(
new ArraySegment<byte>(Encoding.UTF8.GetBytes(message)),
WebSocketMessageType.Text, true, CancellationToken.None));
? ? ? ? ? ? await Task.WhenAll(tasks);
}
? ? ? ? public async Task BroadcastAsync(SocketMessage message)
{
var serializedMessage = JsonConvert.SerializeObject(message);
await NotifyClientsAsync(serializedMessage);
}
}
3.創建 WebSocket 控制器
該控制器將處理 WebSocket 連接。
[Route("ws")]
[ApiController]
public class WebSocketController : ControllerBase
{
private readonly IWebSocketService _webSocketService;
? ? public WebSocketController(IWebSocketService ?webSocketService)
{
_webSocketService= webSocketService;
}
? ? [HttpGet]
public async Task Get()
{
if (HttpContext.WebSockets.IsWebSocketRequest)
{
using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
await _webSocketService.AddSocketAsync(webSocket);
}
else
{
HttpContext.Response.StatusCode = 400;
}
}
}
4. 將 WebSocketService 注入服務
在Program.cs中注冊WebSocketService和IWebSocketService,以便可以在整個應用程序中使用它。
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<IWebSocketService,WebSocketService>();
var app = builder.Build();
app.UseWebSockets();
app.MapControllers();
app.Run();
5. 通知客戶端 API 操作中的任何操作
修改您的 API 控制器以發送通知。
[Route("api/customers")]
[ApiController]
public class HomeController: ControllerBase
{
private readonly IWebSocketService _webSocketService;
? ? public CustomerController(IWebSocketService ?webSocketService)
{
_webSocketService= webSocketService;
}
? ? [HttpPost]
public async Task<IActionResult> Create([FromBody] Model model)
{
// Save customer to DB (your logic)
? ? ? ? // Notify clients
await _webSocketService.NotifyClientsAsync("New model added!");
? ? ? ? return Ok();
}
}
6. 從前端連接
使用 JavaScript 監聽來自 WebSocket 的消息。
const socket = new WebSocket("ws://localhost:5000/ws");
socket.onmessage = function(event) {
console.log("Notification received:", event.data);
};
socket.onopen = function() {
console.log("WebSocket connected!");
};
如果您喜歡此文章,請收藏、點贊、評論,謝謝,祝您快樂每一天。