首页 > 编程语言 >C# WebSocket Fleck 源码解读

C# WebSocket Fleck 源码解读

时间:2024-08-22 23:28:06浏览次数:9  
标签:Socket C# SocketWrapper 源码 Fleck byte 方法

最近在维护公司旧项目,偶然发现使用Fleck实现的WebSocket主动推送功能,(由于前端页面关闭时WebSocket Server中执行了多次OnClose事件回调并且打印了大量的关闭日志,),后来我特地看了源码,这里做一些分享

github: https://github.com/statianzo/Fleck

 在源码中,作者在 Samples 项目中贴心的准备了Server端和 前端Html文件供调试

 打开后,我们稍微改动一下Server.cs类,模拟实际场景向客户端主动推送消息。

运行ConsoleApp项目,随后在浏览器中打开client.html,我们就可以看到客户端接收到很多主动推送的消息

关闭客户端后,此时我们会发现控制台上打印了好多“Close!”,并且抛出了异常,异常是从System.Net.Sockets.NetworkStream 抛出,说我们访问了已释放的对象。

 大概猜测的是程序并发太高了,Socket已经关闭释放的同时,我们任然在向流写入byte字节发送消息。

 

接下来我们读一下源码

首先是 WebSocketServer.cs,构造方法中创建了 System.Net.Sockets.Socket类,并传递给 Fleck.SocketWrapper,后续和Socket相关的操作都是由SocketWrapper实例进行执行。SupportDualStack为True时表示启用IPV6

 随后我们看一下 WebSocketServer.Start() 方法,方法的入参是一个Action,IWebSocketConnection 中我们定义了OnOpen、OnClose、OnMessage等方法。

Start()方法中给SocketWrapper(或System.Net.Sockets.Socket类)类绑定了侦听地址和端口。

ListenForClients() 方法为开始接收连接(Accept),如果有连接,则调用OnClientConnect()方法,OnClientConnect()方法调用中如果出现异常,则执行重启Socket工作。

 

 我们再来看看OnClientConnect()方法做了什么,ListenForClients() 方法是继续侦听客户端连接,随后创建了WebSocketConnection类对象,然后开始connection.StartReceiving() 也就是读取消息内容。

我们可以简单的看一下Fleck.SocketWrapper类的实现,特别是Accept()方法和Receive()方法,其实就是Task执行BeginAccept()、EndAccept()、BeginRead() 和 EndRead() 方法,如果调用时出现异常,则执行Action<Exception>()方法。

接下来我们看一下WebSocketConnection类,首先是构造方法,

  •   socket:连接Socket实例。
  •   initialize:是我们在WebSocketServer 中配置的OnOpen、OnClose、OnMessage等方法。
  •   handlerFactory:是通过工厂模式创建出对应的Handle对象,其中实现了 Draft76Handler、Hybi13Handler、FlashSocketPolicyRequestHandler 等几种类,将收到的byte[]序列化成对应的消息。
  •   parseRequest:是RequestParser.Parse方法的委托,将byte[]通过UTF8序列化成中文,再通过正则表达式提取关键信息生成WebSocketHttpRequest对象。

其次是Read(List<byte>, byte[]) 方法。就是调用SocketWrapper(或System.Net.Sockets.Socket类)的 Receive()方法读取byte[]并交给Handle对象进行处理,如果byte[]长度为0,则表示关闭断开

最后是SendBytes(byte[], Action)方法,就是调用SocketWrapper(或System.Net.Sockets.Socket类)的 Send()方法,如果发送不成功,则会调用CloseSocket()方法关闭Socket(这就是为什么连接只有一个但多次触发OnClose事件原因)

 

Fleck 的核心功能已经讲解完了,其他类还有 WebSocketConnectionInfo、QueuedStream、SubProtocolNegotiator等类基本也是比较简单,这里就不展开讲解了。

Fleck 源码 用了装饰者模式、工厂模式等设计模式,还很优雅的处理方法执行失败的异常方式,对委托的使用也是值得我们学习的。

 

标签:Socket,C#,SocketWrapper,源码,Fleck,byte,方法
From: https://www.cnblogs.com/KarlAlbright/p/18374835

相关文章

  • C:每日一题:双指针法的使用
    前言:思虑再三,觉得如果有时间每日一题还是可以更新一下的。题目难度:基础解题方法:双指针法一、题目输入一个整数数组,实现一个函数来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,所有偶数位于数组的后半部分。二、题目分析本题目标:将给定的整数数组中......
  • C++模板的细节改进
    emsp;emsp;C++11改进了编译器的解析规则,尽可能的将多个右尖括号(>)解析称模板参数结束符,方便我们编写模板相关的代码。1.模板的右尖括号emsp;emsp;在C++98/03的泛型编程中,模板实例化有一个很繁琐的地方,那就是连续两个右尖括号(>>)会被变异器解释称右移操作符,而不是模板参数表的结束......
  • Oracle dataguard 搭建 oracle 11g ADG
    文章目录一、系统环境检查二、参数调整三、搭建ADG1、主库操作1、主库开启归档模式,此步骤需要重启数据库--5主库打开forcelogging--6主库修改DG相关参数--7修改之后验证:--8、主库添加standbyredologfile(根据MAA最佳实践,我们建议只为备用重做日志组,每......
  • 实用工具:[TrafficMonitor]任务栏电脑性能监控安装指南
    实用工具:任务栏电脑性能监控安装指南[TrafficMonitor]效果图话不多说,直接上软件效果图:内容介绍支持监控的指标:上传下载CPU利用率内存利用率CPU温度总网速CPU频率显卡利用率显卡温度硬盘温度主板温度硬盘利用率一共支持12种性能监控指标,相当的丰富安装教程:下载我们......
  • Java核心API——collection类的常见方法
    1、数组与集合之间的转换*集合转换为数组*Collection提供了一个方法toArray。可以将当前集合转换为一个数组Collection<String>array=newArrayList<>();array.add("1");array.add("2");array.add("3");array.add("......
  • 存在重复元素 II(LeetCode)
    题目        给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i]==nums[j] 且 abs(i-j)<=k 。如果存在,返回 true ;否则,返回 false 。解题"""时间复杂度为O(n),空间复杂度为O(min(n,k)),其中n......
  • Scratch创意工坊:启程编程与创造的无限旅程
    标题:Scratch创意工坊:启程编程与创造的无限旅程Scratch,这款由麻省理工学院媒体实验室开发的图形化编程工具,已经成为全球少儿编程教育的璀璨明星。它以独特的拖拽式编程积木,引领孩子们进入充满无限可能的编程世界。本文将详细介绍Scratch如何通过项目模板和示例代码,帮助初学......
  • Scratch编程深度探索:解锁递归与分治算法的奥秘
    标题:Scratch编程深度探索:解锁递归与分治算法的奥秘在编程的世界里,递归和分治算法以其精妙的逻辑结构和解决问题的能力而著称。Scratch,这款专为儿童和初学者设计的图形化编程工具,是否能够支持实现这样复杂的逻辑呢?本文将深入探讨Scratch在实现递归和分治算法方面的能力,并提......
  • 自学C语言
    DAY#0一开始(好好学习,提前内卷!)后面……什么鬼,电子信息工程到底是什么,我要学什么然后#宋浩高数#,#每日英语#学着学着劲头就没了,啊啊啊小说我来了》~《然后又是浑浊,挣扎最近加入了校园的科协预备群,www,一下子感觉亚历山大了(因为看过学长分享,非常想进去,他高一就是进了科协)要学的......
  • 自学C语言
    DAY#3哎,今天忙了很多事,晚上九点才碰到电脑。没什么时间学电脑,又补了一点电脑常识,关于文件还有C盘的一些常识(C盘真的非常非常重要!!)早上弄了校园卡(大学真是个神奇的东西)下午忙忙忙,晚上又学了一点基础知识。和家人发生了矛盾,我好难过/-||||DAY#4(啊啊啊啊,昨天的怎么没有发送......