深入解析Fleck WebSocket库源码
最近在维护公司旧项目时,偶然发现了使用Fleck实现的WebSocket主动推送功能。在调试过程中,发现了一些问题,特地查看了源码,现在分享给大家。
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源码用了装饰者模式、工厂模式等设计模式,还很优雅地处理方法执行失败的异常方式,对委托的使用也是值得我们学习的。
以上就是电脑114游戏给大家带来的关于深入解析Fleck WebSocket库源码全部内容,更多攻略请关注电脑114游戏。
电脑114游戏-好玩游戏攻略集合版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!