1、Fleck这个是实现websocket一个比较简单第三方组件,它不需要安装额外的容器。本身也就几个接口可供调用。
2、项目是基于.netframework4.7.2,在vs2019上开发的,没试过在低版本上运行。但是代码上没怎么用到新特性,所以估计是可以被低版本使用的。
3、这个项目并不是真实项目,也就是玩一下,但是对熟悉Fleck或者了解及时聊天,应该有一丁点的启发作用。
1、最简单、最常用的调用方法:(ws://172.10.3.4:8111改成您的服务器本地IP和端口)
//控制台代码varserver=newWebSocketServer("ws://172.10.3.4:8111");server.Start(socket=>{socket.OnOpen=()=>Console.WriteLine("产生连接处理");socket.OnClose=()=>Console.WriteLine("连接断开处理");socket.OnMessage=(message)=>{//1、此方法用于接收客户端发送来的消息//2、可以做一些自己的操作,例如存入数据库//3、为了响应客户端,一般会使用下面的send函数,返回响应结果。socket.Send(message);}});2、Fleck本身只负责帮你单线联系。也就是客户端A和服务器建立连接后,会产生一个IWebSocketConnection,也就是上面代码中socket变量的类型,它包含了接收方法、发送方法,但是都仅限于单一连接内。至于客户端A想发送消息给客户端B、C、D亦或者想群发,不好意思Fleck本身不Care。。。当然了那并不是这个功能就不能实现了,只是要开发者自己去把每一个IWebSocketConnection存储起来,并管理他们的生存周期,通过自己的代码去实现客户端A给B发信息或者群发。
三、聊天室源码位置
四、核心代码说明。
1、IWebSocketHelper接口。因为一开始,我是想用多个插件来实现聊天室,所以想用一个接口来做行为封装。结果完成了Fleck之后,发现其他的操作模式都不太相同,很难封装就放弃了,但是保留这个接口,是为了体现扩展性。
///
①委托从使用形式来说,是指我们可以把一个函数作为参数进行传递,例如我们在解一道数学题,条件和要求都是一样的,但是求解的过程可以多种多样,通过委托就可以在不改变主体程序的同时,把不同的求解过程,封装到不同的函数中,然后把函数作为参数传入主体程序。
②委托从模式的角度来说,是在实现观察者模式。订阅者\观察者告诉发布者\主题,如果发生了某一特定事情该怎么处理,“怎么处理”的过程就是委托方法的内容
③事件其实就是一个委托,都说事件是一个特殊委托,特殊在哪里,特殊在它对委托增加了约束,让你不能毫无顾忌的使用委托,这是为了保证封装性。
④上面的4个事件,其实我可以直接换成4个委托属性,对程序运行不会有太大影响。但是为什么要使用事件,还是第三点的封装性。事件本来的用意,是达到特定条件后让发布者自己来触发委托方法的执行,但是如果使用委托属性,订阅者本身就可以进行调用,封装性就很差。
⑤上面的4个事件,分别是订阅者告诉Fleck中心,新长连接接通怎么办、长连接断开怎么办、客户端发来消息怎么办、要返回客户端的消息怎么转换。
2、Fleck类的实现。Fleck实现了IWebSocketHelper接口,这是这个项目的核心代码。
②前面说过,Fleck只负责单线联系,每一个连接都是一个IWebSocketConnection,所以我需要把IdentityMd5和IWebSocketConnection存起来,方便索引调用。
③socket.OnMessage中,socketListHs是存储IWebSocketConnection的集合,每次有消息发来,如果判断是新的IdentityMd5就会存起来。
④socket.OnClose中,如果有连接断开了,IWebSocketConnection就会为null,所以遍历集合,然后把值为null剔除就能保持socketListHs集合的有效性
⑥socket.OnOpen、socket.OnClose、socket.OnMessage都是Fleck自行触发的事件,前面一开始我们介绍过了,例如OnOpen中,如果我们需要当建立新连接时记录日志,我们就可以对WsOpenEventHandler赋值(本项目在Global.asax的Application_Start中用lambda赋值),如下:
varsocket;varwebsocketInit=function(wsPath){if(typeof(WebSocket)==="undefined"){socket=null;console.log("浏览器不支持websocket");}else{//实例化socketsocket=newWebSocket(wsPath);//监听socket连接socket.onopen=wsOnOpen;//监听socket关闭socket.onclose=wsOnClose;//监听socket错误信息socket.onerror=wsOnError;//监听socket消息socket.onmessage=wsOnMessage;}}varwsOnOpen=function(){console.log("已经成功连接");varsMsg="";varsendMsg="{\"IdentityMd5\":\""+identityMd5+"\",\"SMsg\":\"\",\"ImgIndex\":\""+imgIndex+"\",\"IsConnSign\":\"true\"}";socket.send(sendMsg);}varwsOnClose=function(){console.log("已经关闭连接");}varwsOnError=function(evt){console.log("异常:"+evt);}varwsSend=function(sMsg){if(socket==null||sMsg=="")returnfalse;console.log("消息成功发出");socket.send(sMsg);}①WebSocket是浏览器内置的一个类型,现在一般的浏览器都支持,但是还是typeof(WebSocket)来做一下判断。
②然后在启动时加载即可(ws://14.215.177.1:8111改成您的服务器公网IP和端口)。
$(function(){websocketInit("ws://14.215.177.1:8111");});
**********End*****************
上面这些也只是部分代码,需要可运行代码,请去github下载源码。
疫情当前,公司发展不顺,旧项目停摆,新项目需求不明。像当前这样的企业破产潮,我是比较紧张的,毕竟不是小年轻,技术又不是特别过硬,不上不下的焦虑的很。但是也明白,行动起来,每天让自己靠近目标一点点,是解决焦虑的不二法门。
能写一些博客,就写一些博客吧,我也不确定写这个对我自己有什么帮助,对读者都多大的帮助,就当备忘录吧。