.net websocket 使用

系列文章目录

目录

文章目录

前言

一、websocket是什么?

一、工作原理

二、特点与优势

三、应用场景

四、缺点与挑战

二、使用步骤

1.引入库

2.如何使用

总结


文章目录

  • websocket 在.net中使用
  • 前言
  • 一、websocket 是什么?
  • 二、使用步骤
    • 1.引入库
    • 2.如何使用
  • 总结


前言

WebSocket是一种网络通信协议,旨在解决传统HTTP协议在实时通信方面的不足。


一、websocket是什么?

WebSocket是一种在单个TCP连接上进行全双工通信的协议。它允许客户端与服务器之间进行持久的、双向的通信,而无需像传统HTTP那样需要客户端不断发起请求来检查服务器是否有新数据。WebSocket协议在2008年首次提出,2011年被IETF(互联网工程任务组)作为标准RFC 6455发布,并由W3C(万维网联盟)进行标准化。

一、工作原理

WebSocket的工作原理可以分为三个阶段:握手、数据传输和断开连接。

  1. 握手:客户端通过发送一个特殊的HTTP请求头来向服务器发起WebSocket连接请求。这个请求中包含了一些特定的字段,如UpgradeConnectionSec-WebSocket-Key等,用于表明客户端希望将协议从HTTP升级到WebSocket。服务器在接收到这个请求后,会进行验证,并返回一个包含Sec-WebSocket-Accept字段的HTTP响应头,表示握手成功,双方建立了WebSocket连接。
  2. 数据传输:一旦建立了WebSocket连接,客户端和服务器就可以通过该连接进行双向的实时数据传输。数据以帧的形式进行传输,每个帧都包含了一些特定的字段,如FIN(表示该帧是否是消息的最后一帧)、Opcode(指定该帧的类型,如文本帧或二进制帧)、Mask(表示是否对数据进行了掩码处理)、Payload Length(数据的长度)以及Payload Data(实际发送的数据)。
  3. 断开连接:当连接不再需要时,客户端或服务器可以发起关闭连接的请求。双方会交换特殊的关闭帧,以协商关闭连接,并确保双方都接收到了关闭请求。

二、特点与优势

  1. 全双工通信:与传统HTTP请求/响应模式不同,WebSocket可以同时进行发送和接收数据。这意味着服务器可以主动向客户端发送数据,而不需要客户端先发起请求。
  2. 低延迟:由于建立了持久连接,并且数据传输没有额外的HTTP头部信息负担,因此WebSocket能够更快地传输小量数据。
  3. 节省带宽:WebSocket只需要一个TCP握手就能创建一个到服务器的链接,并且这个链接可以被复用以节省带宽。
  4. 跨域问题简单:在正确配置后,WebSocket允许跨域通讯。
  5. 适用于实时应用:对于聊天、游戏、实时交易等实时性要求高的应用,WebSocket能够提供更好的服务。

三、应用场景

WebSocket在实际应用中具有广泛的应用场景,包括但不限于:

  1. 实时聊天应用:如在线聊天室、即时通讯软件等,用户可以实时地发送和接收消息,提高了沟通效率。
  2. 在线游戏:实现游戏数据的实时传输和同步,为玩家提供更好的游戏体验。
  3. 实时数据监控:如股票价格、天气信息、交通状况等,服务器可以实时地将最新的数据推送给客户端。
  4. 协同办公:如在线文档编辑、实时会议等,多个用户可以同时编辑同一个文档或代码文件,他们的编辑结果会实时地同步到其他用户的界面上。
  5. 物联网(IoT):用于设备的远程监控和控制,允许实时收集和传输设备数据。

四、缺点与挑战

尽管WebSocket具有诸多优势,但也存在一些缺点和挑战:

  1. 兼容性问题:虽然大多数现代浏览器都支持WebSocket,但是一些老版本浏览器可能不支持。此外,一些网络代理和防火墙可能会阻止WebSocket连接。
  2. 安全性问题:WebSocket虽然在协议上支持加密(如WSS,即加密的WebSocket),但它并没有像HTTP那样有完善成熟的安全策略。开发者需要自己去处理安全性问题,如校验消息内容等。
  3. 服务器压力较高:由于需要保持长连接,所以会占用较多的服务器资源。这对服务器的性能和管理提出了更高的要求。
  4. 不适合大数据量传输:WebSocket更适合频繁、小数据量传输。对于大文件或大数据量传输来说,可能并不是最理想的选择。

综上所述,WebSocket作为一种现代Web实时通信的核心技术,具有显著的优势和广泛的应用场景。然而,在使用WebSocket时也需要考虑其兼容性问题、安全性问题以及服务器资源管理等挑战。

二、使用步骤

1.引入库

代码如下(示例):

using System;
using System.Collections.Generic;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.WebSockets;

2.如何使用

1.新建帮助类

代码如下(示例):


using System;
using System.Collections.Generic;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.WebSockets;namespace Xhxx.WebSockets;public class WebSocketHandler
{private WebSocket _webSocket;private int frameBytesCount = 10240;public event EventHandler Opened;public event EventHandler<string> TextMessageReceived;public event EventHandler Closed;public virtual async Task ProcessRequest(AspNetWebSocketContext context){_webSocket = context.WebSocket;RaiseOpenEvent();while (_webSocket.State == WebSocketState.Open){List<byte> receivedBytes = new List<byte>();ArraySegment<byte> buffer2 = WebSocket.CreateServerBuffer(frameBytesCount);WebSocketReceiveResult receiveResult = await _webSocket.ReceiveAsync(buffer2, CancellationToken.None);if (receiveResult.MessageType == WebSocketMessageType.Close){await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);RaiseOnClosed();break;}WebSocketMessageType messageType = receiveResult.MessageType;MergeFrameContent(receivedBytes, buffer2.Array, receiveResult.Count);while (!receiveResult.EndOfMessage){buffer2 = WebSocket.CreateServerBuffer(frameBytesCount);receiveResult = await _webSocket.ReceiveAsync(buffer2, CancellationToken.None);MergeFrameContent(receivedBytes, buffer2.Array, receiveResult.Count);}RaiseMessageArrive(receivedBytes.ToArray(), messageType, receivedBytes.Count);}}public virtual async Task SendMessage(string message){if (_webSocket == null || _webSocket.State != WebSocketState.Open){throw new InvalidOperationException("the web socket is not open.");}byte[] bytes = Encoding.UTF8.GetBytes(message);for (int sentBytes = 0; sentBytes < bytes.Length; sentBytes += frameBytesCount){int remainingBytes = bytes.Length - sentBytes;await _webSocket.SendAsync(new ArraySegment<byte>(bytes, sentBytes, (remainingBytes > frameBytesCount) ? frameBytesCount : remainingBytes), WebSocketMessageType.Text, endOfMessage: true, CancellationToken.None);}}protected void MergeFrameContent(List<byte> destBuffer, byte[] buffer, long count){count = ((count < buffer.Length) ? count : buffer.Length);if (count == buffer.Length){destBuffer.AddRange(buffer);return;}byte[] array = new byte[count];Array.Copy(buffer, array, count);destBuffer.AddRange(array);}protected void RaiseOpenEvent(){this.Opened?.Invoke(this, EventArgs.Empty);}protected void RaiseMessageArrive(byte[] buffer, WebSocketMessageType type, long count){if (type == WebSocketMessageType.Text && this.TextMessageReceived != null){this.TextMessageReceived(this, Encoding.UTF8.GetString(buffer));}}protected void RaiseOnClosed(){this.Closed?.Invoke(this, EventArgs.Empty);}
}

2使用帮助类

      private static Dictionary<string, WebSocketHandler> _handlers = new Dictionary<string, WebSocketHandler>();
public HttpResponseMessage Connect(string nickName)
{var webSocketHandler = new WebSocketHandler();if (_handlers.ContainsKey(nickName)){return Request.CreateResponse(HttpStatusCode.BadRequest);}_handlers[nickName] = webSocketHandler;webSocketHandler.TextMessageReceived += (sendor, Parameter) =>{try{WebSocketDto _para = Newtonsoft.Json.JsonConvert.DeserializeObject<WebSocketDto>(Parameter);if (_para == null){_handlers.Remove(nickName);result.code = (int)Const.c_code.参数错误;result.message = Const.c_code.参数错误.ToString();SendMessage(nickName, result.ToJson());}else{_para.nickName = nickName;if (_para.queryType == (int)QuestType.Login){DealMainLogin(_para);}if (_para.queryType == (int)QuestType.Agent){DealMainAgent(_para);}if (_para.queryType == (int)QuestType.xintiao){result.code = (int)QuestType.xintiao;result.message = "恭喜,您目前处于活蹦乱跳状态 ^_^ ";SendMessage(nickName, result.ToJson());}}}catch (Exception ex){_handlers.Remove(nickName);result.code = (int)Const.c_code.抛出异常;result.message = ex.Message;SendMessage(nickName, result.ToJson());}};webSocketHandler.Closed += (sendor, arg) =>{if (nickName.Contains("login_")){ClosedLogin(nickName);}_handlers.Remove(nickName);};webSocketHandler.Opened += (sendor, arg) =>{result.message = "连接成功...";SendMessage(nickName, result.ToJson());};HttpContext.Current.AcceptWebSocketRequest(webSocketHandler);return Request.CreateResponse(HttpStatusCode.SwitchingProtocols);
}/// <summary>/// 发送数据/// </summary>/// <param name="sendorNickName"></param>/// <param name="message"></param>private void SendMessage(string sendorNickName, string message, bool Broadcast = false){foreach (var handlerKvp in _handlers){if (Broadcast){//广播发送handlerKvp.Value.SendMessage(message).Wait();}else{//点对点发送if (handlerKvp.Key == sendorNickName){handlerKvp.Value.SendMessage(message).Wait();}}}}

总结

这就是相关的websocket 使用方法

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

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

相关文章

每日Attention学习24——Strip Convolution Block

模块出处 [TIP 21] [link] CoANet: Connectivity Attention Network for Road Extraction From Satellite Imagery 模块名称 Strip Convolution Block (SCB) 模块作用 多方向条形特征提取 模块结构 模块特点 类PSP设计&#xff0c;采用四个并行分支提取不同维度的信息相比于…

用FileZilla Server 1.9.4给Windows Server 2025搭建FTP服务端

FileZilla Server 是一款免费的开源 FTP 和 FTPS 服务器软件&#xff0c;分为服务器版和客户端版。服务器版原本只支持Windows操作系统&#xff0c;比如笔者曾长期使用过0.9.60版&#xff0c;那时候就只支持Windows操作系统。当时我们生产环境对FTP稳定性要求较高&#xff0c;比…

es-head(es库-谷歌浏览器插件)

1.下载es-head插件压缩包&#xff0c;并解压缩 2.谷歌浏览器添加插件 3.使用

健康检查、k8s探针、Grails+Liquibase框架/health 404 Not Found排查及解决

概述 健康检查对于一个pod而言&#xff0c;其重要性不言而喻。 k8s通过探针来实现健康检查。 探针 k8s提供三种探针&#xff1a; 存活探针&#xff1a;livenessProbe就绪探针&#xff1a;readinessProbe启动探针&#xff1a;startupProbe 存活探针 存活探针决定何时重启…

5个GitHub热点开源项目!!

1.自托管 Moonlight 游戏串流服务&#xff1a;Sunshine 主语言&#xff1a;C&#xff0c;Star&#xff1a;14.4k&#xff0c;周增长&#xff1a;500 这是一个自托管的 Moonlight 游戏串流服务器端项目&#xff0c;支持所有 Moonlight 客户端。用户可以在自己电脑上搭建一个游戏…

【Linux C | 时间】localtime 的介绍、死机、死锁问题以及 localtime_r 函数的时区问题

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

122. 买卖股票的最佳时机 II 反向递推的方法

下面是将你提供的代码整理成一篇Markdown格式的博客内容&#xff1a; 股票买卖的最大利润 问题描述 给定一个整数数组 prices&#xff0c;其中 prices[i] 是股票在第 i 天的价格。你可以选择在某一天买入股票&#xff0c;并在之后的某一天卖出股票。要求计算出你能够获得的最…

详解Tomcat下载安装以及IDEA配置Tomcat(2023最新)

目录 步骤一&#xff1a;首先确认自己是否已经安装JDK步骤二&#xff1a;下载安装Tomcat步骤三&#xff1a;Tomcat配置环境变量步骤四&#xff1a;验证Tomcat配置是否成功步骤五&#xff1a;为IDEA配置Tomcat 步骤一&#xff1a;首先确认自己是否已经安装JDK jdk各版本通用安…

html中的css

css &#xff08;cascading style sheets&#xff0c;串联样式表&#xff0c;也叫层叠样式表&#xff09; css规范一般约定&#xff1a; 1.存放CSS样式文件的目录一般命名为style或css。 2.在项目初期&#xff0c;会把不同类别的样式放于不同的CSS文件&#xff0c;是为了CSS编…

前端项目配置初始化

creat-vue 安装 https://cn.vuejs.org/guide/quick-start.html 官网复制npm安装语句 cmd窗口创建文件夹 npm create vue3.12.2安装webstorm启动vue项目 https://www.jetbrains.com/webstorm/download/other.html 2024.3.2.1 安装依赖 下载包node_modules package 运行服…

Java注解的原理

目录 问题: 作用&#xff1a; 原理&#xff1a; 注解的限制 拓展&#xff1a; 问题: 今天刷面经&#xff0c;发现自己不懂注解的原理&#xff0c;特此记录。 作用&#xff1a; 注解的作用主要是给编译器看的&#xff0c;让它帮忙生成一些代码&#xff0c;或者是帮忙检查…

seacmsv9注入管理员账号密码+orderby+limit

seacmsv9注入管理员账号密码 安装海洋CMS&#xff08;seacms&#xff09; 将upload文件夹里的文件全部上传至网页服务器后&#xff0c;执行以下操作: 请运行http://域名/install/index.php进行程序安装 SQL语句尝试注入 http://127.0.0.1/upload/comment/api/index.php?g…

【构建工具】Gradle Kotlin DSL中的大小写陷阱:BuildConfigField

在Android开发当中&#xff0c;BuildConfig是一个非常有用的功能&#xff0c;它允许我们在构建过程中定义常量&#xff0c;并在运行时使用它们。But&#xff01;&#xff01;当我们从传统的Groovy DSL迁移到Kotlin DSL时或者被Android Studio坑的时候&#xff0c;有一些细微的差…

AI如何改变传统工厂的生产模式?

随着第四次工业革命的浪潮席卷全球&#xff0c;制造业的数字化转型成为企业在竞争中脱颖而出的关键。过去&#xff0c;传统制造业往往依赖于大量的人工操作和低效率的管理流程&#xff0c;而如今&#xff0c;智能化、自动化、数据化已经成为未来制造业的必由之路。从车间到云端…

Redis

redis启动命令 默认端口启动redis&#xff1a; redis-server redis.windows.conf 指定端口9001和9002启动redis(需要新建配置文件&#xff0c;并修改配置文件port属性)&#xff1a; redis-server .\redis-9001.conf redis-server .\redis-9002.conf 检查是否启动Redis &#…

洛谷 P8705:[蓝桥杯 2020 省 B1] 填空题之“试题 E :矩阵” ← 卡特兰数

【题目来源】 https://www.luogu.com.cn/problem/P8705 【题目描述】 把 1∼2020 放在 21010 的矩阵里。要求同一行中右边的比左边大&#xff0c;同一列中下边的比上边的大。一共有多少种方案? 答案很大&#xff0c;你只需要给出方案数除以 2020 的余数即可。 【答案提交】 …

ARM 处理器平台 eMMC Flash 存储磨损测试示例

By Toradex秦海 1). 简介 目前工业嵌入式 ARM 平台最常用的存储器件就是 eMMC Nand Flash 存储&#xff0c;而由于工业设备一般生命周期都比较长&#xff0c;eMMC 存储器件的磨损寿命对于整个设备来说至关重要&#xff0c;因此本文就基于 NXP i.MX8M Mini ARM 处理器平台演示…

14.二叉搜索树

二叉搜索树 1.概念 ⼆叉搜索树⼜称⼆叉排序树&#xff0c;它或者是⼀棵空树&#xff0c;或者是具有以下性质的⼆叉树: *若它的左⼦树不为空&#xff0c;则左⼦树上所有结点的值都⼩于等于根结点的值 *若它的右⼦树不为空&#xff0c;则右⼦树上所有结点的值都⼤于等于根结点…

8、HTTP/1.0和HTTP/1.1的区别【高频】

第一个是 长连接&#xff1a; HTTP/1.0 默认 短连接&#xff0c;&#xff08;它也可以指定 Connection 首部字段的值为 Keep-Alive实现 长连接&#xff09;而HTTP/1.1 默认支持 长连接&#xff0c;HTTP/1.1是基于 TCP/IP协议的&#xff0c;创建一个TCP连接是需要经过三次握手的…

【爬虫基础】第二部分 爬虫基础理论 P1/3

上节内容回顾&#xff1a;【爬虫基础】第一部分 网络通讯 P1/3-CSDN博客 【爬虫基础】第一部分 网络通讯-Socket套接字 P2/3-CSDN博客 【爬虫基础】第一部分 网络通讯-编程 P3/3-CSDN博客 爬虫相关文档&#xff0c;希望互相学习&#xff0c;共同进步 风123456789&#xff…