C#的WebSocket使用简记_system.net.websockets-程序员宅基地

技术标签: c#  websocket  C# .net  异步操作  WebSocket  

ClientWebSocket

这里用到的核心代码就是ClientWebSocket类。提供用于连接到WebSocket服务的客户端。

  • 程序集:System.Net.WebSockets.Client.dll;
  • 命名空间:System.Net.WebSockets;
  • 继承:Object—>WebSocket—>ClientWebSocke;

csharp public sealed class ClientWebSocket : System.Net.WebSockets.WebSocket

属性

属性 作用
CloseStatus 获取在ClientWebSocket实例上启动关闭握手的原因。
CloseStatusDescription 获取对关闭ClientWebSocket实例的原因的描述。
Options 获取ClientWebSocket实例的WebSocket选项。
State 获取ClientWebSocket实例的WebSocket状态。
SubProtocol 获取ClientWebSocket实例支持的WebSocket子协议。

方法

方法 作用
Abort() 中止连接并取消任何挂起的IO操作。
CloseAsync(WebSocketCloseStatus, String, CancellationToken) 关闭作为异步操作的ClientWebSocket实例。
CloseOutputAsync(WebSocketCloseStatus, String, CancellationToken) 关闭作为异步操作的ClientWebSocket实例的输出。
ConnectAsync(Uri, CancellationToken) 连接到WebSocket服务器以作为异步操作。
Dispose() 释放ClientWebSocket实例使用的非托管资源。
Equals(Object) 确定指定对象是否等于当前对象。(继承自Object)
GetHashCode() 作为默认哈希函数。(继承自Object)
GetType() 获取当前实例的Type。(继承自Object)
MemberwiseClone() 创建当前Object的浅表副本。(继承自Object)
ReceiveAsync(ArraySegment<Byte>, CancellationToken) ClientWebSocket上的数据作为异步操作进行接收。
ReceiveAsync(Memory<Byte>, CancellationToken) ClientWebSocket上的数据作为异步操作进行接收。
SendAsync(ArraySegment<Byte>, WebSocketMessageType, Boolean, CancellationToken) 以异步操作方式,发送ClientWebSocket上的数据。
SendAsync(ReadOnlyMemory<Byte>, WebSocketMessageType, Boolean, CancellationToken) 以异步操作方式,从只读字节内存范围发送ClientWebSocket上的数据。
ToString() 返回表示当前对象的字符串。(继承自Object)

代码

以下是我项目中用到的父类实例,仅供参考:

using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;

/// <summary>WebSocket链接</summary>
public class WebSocketLink
{
    
    public WebSocketLink(string url)
    {
    
        m_uri = new Uri(url);
        m_client = new ClientWebSocket();
        m_cToken = new CancellationToken();
    }

    protected readonly Uri m_uri = null;
    /// <summary>WebSocket客户端对象</summary>
    protected readonly ClientWebSocket m_client = null;
    protected readonly CancellationToken m_cToken;
    /// <summary>接收WebSocket返回的信息数据</summary>
    protected WebSocketReceiveResult m_websocketReceiveResult = null;
    /// <summary>byte数组,用于接收WebSocket返回的数据</summary>
    protected byte[] m_byteArrBuffer = null;
    /// <summary>接收WebSocket返回的字符串数据</summary>
    protected string m_result = null;

    /// <summary>是否循环(链接处于打开状态)</summary>
    protected bool Loop {
     get {
     return m_client.State == WebSocketState.Open; } }

    /// <summary>获取缓冲区的byte数组段</summary>
    /// <param name="arr">byte数组内容</param>
    /// <returns>结果byte数组段</returns>
    protected ArraySegment<byte> GetBuffer(byte[] arr)
    {
    
        return new ArraySegment<byte>(arr);
    }
    /// <summary>获取缓冲区的byte数组段</summary>
    /// <param name="str">字符串内容</param>
    /// <returns>结果byte数组段</returns>
    protected ArraySegment<byte> GetBuffer(string str)
    {
    
        return GetBuffer(Encoding.UTF8.GetBytes(str));
    }
    /// <summary>接收信息</summary>
    /// <returns>返回值为WebSocketReceiveResult的Task</returns>
    protected async Task<WebSocketReceiveResult> ReceiveMessage()
    {
    
        m_byteArrBuffer = new byte[1024];
        WebSocketReceiveResult wsrResult = await m_client.ReceiveAsync(GetBuffer(m_byteArrBuffer), new CancellationToken());//接受数据
        //Debug.Log(wsrResult.Count + "---" + wsrResult.EndOfMessage + "---" + wsrResult.MessageType);
        m_result += Encoding.UTF8.GetString(m_byteArrBuffer, 0, wsrResult.Count);
        return wsrResult;
    }
    /// <summary>解析结果</summary>
    protected virtual void ParseResult()
    {
    

    }
    /// <summary>网络报错</summary>
    /// <param name="ex">错误信息</param>
    protected virtual void WebSocketError(Exception ex)
    {
    
        Debug.LogError(ex.Message + "\n" + ex.StackTrace + "\n" + ex.Source + "\n" + ex.HelpLink);
    }

    /// <summary>连接、接收</summary>
    public async void ConnectAuthReceive()
    {
    
        try
        {
    
            await m_client.ConnectAsync(m_uri, m_cToken);//连接
            while (Loop)
            {
    //遍历接受信息
                m_websocketReceiveResult = await ReceiveMessage();
                if (m_websocketReceiveResult.EndOfMessage)
                {
    //接收完一条完整信息,解析
                    //Debug.Log("完整一条信息:" + m_result);
                    if (string.IsNullOrEmpty(m_result))
                    {
    //正规闭包的返回值
                        break;
                    }
                    ParseResult();
                }
            }
        }
        catch (Exception ex)
        {
    
            WebSocketError(ex);
        }
    }
    /// <summary>发送请求</summary>
    /// <param name="text">请求信息内容</param>
    public async Task SendRequest(string text)
    {
    
        if (m_client.State == WebSocketState.None) {
     Debug.Log("未建立链接!"); return; }
        await m_client.SendAsync(GetBuffer(text), WebSocketMessageType.Text, true, m_cToken);//发送数据
    }
    /// <summary>关闭</summary>
    public async void Close()
    {
    
        if (m_client.State == WebSocketState.None) {
     Debug.Log("未建立链接!"); return; }
        await m_client.CloseAsync(WebSocketCloseStatus.NormalClosure, "正规闭包", m_cToken);
    }
    /// <summary>终止</summary>
    public void Abort()
    {
    
        if (m_client.State == WebSocketState.None) {
     Debug.Log("未建立链接!"); return; }
        m_client.Abort();
    }
}

async/await

代码中使用的是async/await的异步编程:C# async/await异步编程

参考链接

  1. https://docs.microsoft.com/zh-cn/dotnet/api/system.net.websockets.clientwebsocket?view=net-5.0
  2. https://www.cnblogs.com/Jason-c/p/11117002.html
  3. https://blog.csdn.net/weixin_39106746/article/details/104919621
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/f_957995490/article/details/119648882

智能推荐

ASP.NET Core 运行原理解剖[5]:Authentication-程序员宅基地

文章浏览阅读3.1k次。在现代应用程序中,认证已不再是简单的将用户凭证保存在浏览器中,而要适应多种场景,如App,WebAPI,第三方登录等等。在 ASP.NET 4.x 时代的Windows认证和Forms认证已无法满足现代化的需求,因此在ASP.NET Core 中对认证及授权进行了全新设计,使其更加灵活,可以应付各种场景。在上一章中,我们提到HttpContext中认证相关的功能放在了独立的模块中,以扩展的方式来展_.net core authenticationhandler httpcontext

java8特性:list转Map并排序_list转成map且顺序不变-程序员宅基地

文章浏览阅读1.5w次。初始代码public Map&amp;lt;String,List&amp;lt;RgwstBean&amp;gt;&amp;gt; getMap(List&amp;lt;RgwstBean&amp;gt; lists){ Map&amp;lt;String,List&amp;lt;RgwstBean&amp;gt;&amp;gt; map = new TreeMap&amp;lt;String,List&am_list转成map且顺序不变

leaflet通过WFS服务加载geoserver 矢量数据_leaflet geoserver wfs 方式-程序员宅基地

文章浏览阅读5.9k次,点赞5次,收藏16次。leaflet通过WFS服务加载geoserver 矢量数据1.前言2.从geoserver获得geojson数据3.geoserver跨域配置4.根据请求结果生成layer5.完整代码1.前言leaflet默认支持的服务只有WMS,因此不能加载WFS数据,但是leaflet提供了另一个方法geoJson,它的作用是从一个geojson文件中加载地图,所以利用leaflet加载WFS数据的一个..._leaflet geoserver wfs 方式

自定义动画animate_使用animate方法制作任意动画是什么意思-程序员宅基地

文章浏览阅读937次。开发工具与关键技术:VS,MVC作者:陈梅撰写时间:2019年6月2 日所有代码来源与老师教学这次分享一个好玩的自定义动画效果,这次还是用jQuery做出来的小功能。这次我们先直接看最后已经布局好的效果。把所想写的内容填写到p标签中,给到p标签的动画功能是,页面已执行时,p标签的内容就会渐渐消失。在给一个紫色的div盒子,这个盒子要实现四种动画效果,所以给这四个动画效果一个下拉框,选择..._使用animate方法制作任意动画是什么意思

如何在MonogoDB中查看配置的参数值-程序员宅基地

文章浏览阅读1k次。怎样在MongoDB实现mysql show variables like 'xx';例如:1.查看所有参数值:C:\Users\duansf>mongoMongoDB shell version: 2.6..._查看mongodb 默认参数值

【ACO TSP】基于matlab蚁群算法求解旅行商问题【含Matlab源码 1583期】-程序员宅基地

文章浏览阅读863次。蚁群算法求解旅行商问题完整的代码,方可运行;可提供运行操作视频!适合小白!

随便推点

如何深入学习c语言,如何深入学习C语言?-程序员宅基地

文章浏览阅读2.1k次。匿名用户1级2016-09-11 回答其实吧,学习C语言是以后从事软件设计的一个基础。任何领域都需要长时间的投入才有结果,你现在学习了C语言,再学习其他语言的时候就比较上手了。在软件设计中:学习一门语言仅仅是第一阶段:如果你基本掌握了一门语言,那么再想深入学习的话就需要把所有C语言的相关的库函数弄懂,并熟练掌握一个开发平台(如最基础的TC)。这是第二阶段下一阶段你就需要继续学习不同的操作系统所提供..._c语言入门后怎么深入

React Native 嵌入到iOS原生项目_ios原生项目嵌入reactnative 模块-程序员宅基地

文章浏览阅读672次。如果你正准备从头开始制作一个新的应用,那么React Native会是个非常好的选择。但如果你只想给现有的原生应用中添加一两个视图或是业务流程,React Native也同样不在话下。只需简单几步,你就可以给原有应用加上新的基于React Native的特性、画面和视图等。https://zjqian.github.io/2017/05/03/rn-integration-iosNative/_ios原生项目嵌入reactnative 模块

猿创征文 |【Ant Design Pro】使用ant design pro做为你的开发模板(五)去除无效代码,生成一个清晰的开发模板_umi 去除代码的lo-程序员宅基地

文章浏览阅读608次。本次终于写到了第五章了,前面四章节,我们从一个全新的 umi3 的ant design pro 模板开始着手,我们以一个初始者要用它的思想介入,逐步走了新增路由、cssmodules、国际化语言切换、使用mock数据进行快速开发、联调正式接口、初始化配置、登录修改、接口文件提取等等。这次到第五章了,我们暂时不做新的改变,我们来把之前写的一些杂项收拾收拾,比如,清除一些不需要的代码,规范一些东西,让我们的项目成为我们的快速开发模板。_umi 去除代码的lo

Andorid源码编译需要掌握的shell语法(三)_android shell脚本语法 :>-程序员宅基地

文章浏览阅读1.2k次。Android 源码编译文件中语法记录_android shell脚本语法 :>

Linux V4L2子系统分析(一)_v4l2_subdev_call-程序员宅基地

文章浏览阅读4.2k次,点赞12次,收藏72次。1.概述Linux系统上的Video设备多种多样,如通过Camera Host控制器接口连接的摄像头,通过USB总线连接的摄像头等。为了兼容更多的硬件,Linux内核抽象了V4L2(Video for Linux Two)子系统。V4L2子系统是Linux内核中关于Video(视频)设备的API接口,是V4L(Video for Linux)子系统的升级版本。V4L2子系统向上为虚拟文件系统提供了统一的接口,应用程序可通过虚拟文件系统访问Video设备。V4L2子系统向下给Video设备提供接口,同时管理_v4l2_subdev_call

服务器基础配置:浪潮服务器配置ILO地址、修改管理员密码、查看虚拟化是否打开:_浪潮服务器修改管理口密码-程序员宅基地

文章浏览阅读1w次。使用场景:因为在公司机房中的服务器我们在使用需要对他做一些类似于初始化的配置,分别是三个,——》第一个是配置服务器的ILO地址,这个是我们通过网络打开一个Web页面对服务器进行一些操作;——》第二个是对管理用户的密码进行修改,这个是因为不同的服务器初始的管理员的密码也许是不一样的,我们将其修改为统一的方便记忆也方便管理;——》第三个就是开启服务器的半虚拟化功能,这个是我们的公司的也许需要服..._浪潮服务器修改管理口密码

推荐文章

热门文章

相关标签