使用 .NET Core 的原始 WebSocket

        在 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!");
};

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/91834.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/91834.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

编程实现Word自动排版:从理论到实践的全面指南

在现代办公环境中&#xff0c;文档排版是一项常见但耗时的工作。特别是对于需要处理大量文档的专业人士来说&#xff0c;手动排版不仅费时费力&#xff0c;还容易出现不一致的问题。本文将深入探讨如何通过编程方式实现Word文档的自动排版&#xff0c;从理论基础到实际应用&…

力扣经典算法篇-25-删除链表的倒数第 N 个结点(计算链表的长度,利用栈先进后出特性,双指针法)

1、题干 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a;输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5] 示例 2&#xff1a; 输入&#xff1a;head [1], n 1 输出&#xff1a;[] 示例 3&…

VIT速览

当我们取到一张图片&#xff0c;我们会把它划分为一个个patch&#xff0c;如上图把一张图片划分为了9个patch&#xff0c;然后通过一个embedding把他们转换成一个个token&#xff0c;每个patch对应一个token&#xff0c;然后在输入到transformer encoder之前还要经过一个class …

【服务器与部署 14】消息队列部署:RabbitMQ、Kafka生产环境搭建指南

【服务器与部署 14】消息队列部署&#xff1a;RabbitMQ、Kafka生产环境搭建指南 关键词&#xff1a;消息队列、RabbitMQ集群、Kafka集群、消息中间件、异步通信、微服务架构、高可用部署、消息持久化、生产环境配置、分布式系统 摘要&#xff1a;本文从实际业务场景出发&#x…

LeetCode中等题--167.两数之和II-输入有序数组

1. 题目 给你一个下标从 1 开始的整数数组 numbers &#xff0c;该数组已按 非递减顺序排列 &#xff0c;请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] &#xff0c;则 1 < index1 < index2 <…

【C# in .NET】19. 探秘抽象类:具体实现与抽象契约的桥梁

探秘抽象类:具体实现与抽象契约的桥梁 在.NET类型系统中,抽象类是连接具体实现与抽象契约的关键桥梁,它既具备普通类的状态承载能力,又拥有类似接口的行为约束特性。本文将从 IL 代码结构、CLR 类型加载机制、方法调度逻辑三个维度,全面揭示抽象类的底层工作原理,通过与…

Apache RocketMQ + “太乙” = 开源贡献新体验

Apache RocketMQ 是 Apache 基金会托管的顶级项目&#xff0c;自 2012 年诞生于阿里巴巴&#xff0c;服务于淘宝等核心交易系统&#xff0c;历经多次双十一万亿级数据洪峰稳定性验证&#xff0c;至今已有十余年发展历程。RocketMQ 致力于构建低延迟、高并发、高可用、高可靠的分…

永磁同步电机控制算法--弱磁控制(变交轴CCR-VQV)

一、原理介绍CCR-FQV弱磁控制不能较好的利用逆变器的直流侧电压&#xff0c;造成电机的调速范围窄、效率低和带载能力差。为了解决CCR-FQV弱磁控制存在的缺陷&#xff0c;可以在电机运行过程中根据工况的不同实时的改变交轴电压给定uq的值&#xff0c;实施 CCR-VQV弱磁控制。…

达梦数据守护集群搭建(1主1实时备库1同步备库1异步备库)

目录 1 环境信息 1.1 目录信息 1.2 其他环境信息 2 环境准备 2.1 新建dmdba用户 2.2 关闭防火墙 2.3 关闭Selinux 2.4 关闭numa和透明大页 2.5 修改文件打开最大数 2.6 修改磁盘调度 2.7 修改cpufreq模式 2.8 信号量修改 2.9 修改sysctl.conf 2.10 修改 /etc/sy…

电感与电容充、放电极性判断和电感选型

目录 一、电感 二、电容 三、电感选型 一、电感 充电&#xff1a;左右-为例 放电&#xff1a;极性相反&#xff0c;左-右 二、电容 充电&#xff1a;左右-为例 放电&#xff1a;左右-&#xff08;与充电极性一致&#xff09; 三、电感选型 主要考虑额定电流和饱和电流。…

新建模范式Mamba——“Selectivity is All You Need?”

目录 一、快速走进和理解Mamba建模架构 &#xff08;一&#xff09;从Transformer的统治地位谈起 &#xff08;二&#xff09;另一条道路&#xff1a;结构化状态空间模型&#xff08;SSM&#xff09; &#xff08;三&#xff09;Mamba 的核心创新&#xff1a;Selective SSM…

Python实现Word文档中图片的自动提取与加载:从理论到实践

在现代办公和文档处理中&#xff0c;Word文档已经成为最常用的文件格式之一。这些文档不仅包含文本内容&#xff0c;还经常嵌入各种图片、图表和其他媒体元素。在许多场景下&#xff0c;我们需要从Word文档中提取这些图片&#xff0c;例如进行内容分析、创建图像数据库、或者在…

Kafka、RabbitMQ 与 RocketMQ 高可靠消息保障方案对比分析

Kafka、RabbitMQ 与 RocketMQ 高可靠消息保障方案对比分析 在分布式系统中&#xff0c;消息队列承担着异步解耦、流量削峰、削峰填谷等重要职责。为了保证应用的数据一致性和业务可靠性&#xff0c;各大消息中间件都提供了多种高可靠消息保障机制。本文以Kafka、RabbitMQ和Rock…

四足机器人远程视频与互动控制的全链路方案

随着机器人行业的快速发展&#xff0c;特别是四足仿生机器人在巡检、探测、安防、救援等复杂环境中的广泛部署&#xff0c;如何实现高质量、低延迟的远程视频监控与人机互动控制&#xff0c;已经成为制约其应用落地与规模化推广的关键技术难题。 四足机器人常常面临以下挑战&a…

把leetcode官方题解自己简单解释一下

自用自用&#xff01;&#xff01;&#xff01;leetcode hot 100

hive的sql优化思路-明白底层运行逻辑

一、首先要明白底层map、shuffle、reduce的顺序之中服务器hdfs数据文件在内存与存储之中是怎么演变的&#xff0c;因为hive的性能瓶颈基本在内存&#xff0c;具体参考以下他人优秀文章&#xff1a; 1.Hive SQL底层执行过程详细剖析 2.Hive JOIN性能调优 二是要明白hive对应的…

驱动隔离芯片在现代工业上的卓越贡献

在智能时代的精密齿轮中&#xff0c;驱动隔离芯片如同一位精通跨界语言的“安全架构师”&#xff0c;在高压与低压、危险与精密的交界处重构秩序。它不生产数据&#xff0c;却是信息的守门人&#xff1b;不创造能量&#xff0c;却是电流的驯兽师。从钢铁丛林到生命方舟&#xf…

使用MATLAB探索圆周率π的奇妙计算之旅

在数学的璀璨星河中,圆周率π无疑是最耀眼的明星之一。这个看似简单的无理数蕴含着宇宙的奥秘,吸引着无数科学家和数学爱好者探索其计算方法。今天,我们将使用MATLAB这一强大的科学计算工具,踏上π的计算之旅,体验从古典算法到现代技巧的奇妙过程。 1. 蒙特卡洛法:随机的…

React 服务器组件 (RSC)

文章目录前言1. 什么是服务器组件 (Server Components)?2. 服务器组件的核心规则(1) 异步性 (async/await)(2) 无客户端交互(3) 渲染限制3. 与客户端组件的协作组合模式Props 传递规则4. 使用场景5. 文件命名约定6. 常见误区7. 示例代码服务端组件&#xff08;获取数据&#x…

如何解决AttributeError: ‘NoneType‘ object has no attribute问题

如何解决AttributeError: ‘NoneType’ object has no attribute问题 问题背景与概述 在 Python 项目开发和调试过程中&#xff0c;经常会碰到这样一个异常信息&#xff1a; AttributeError: NoneType object has no attribute foo这意味着你尝试访问或调用某个对象的属性&a…