【转】基于WebSocketSharp 的IM 简单实现

websocket-sharp 是一个websocket的C#实现,支持.net 3.5及以上来开发服务端或者客户端。本文主要介绍用websocket-sharp来做服务端、JavaScript做客户端来实现一个简单的IM。

WebSocketBehavior

WebSocketBehavior是核心对象,他包含了OnOpen,OnMessage,OnClose,OnError四个事件(回调)以及一个Sessions对象和一个Send方法。熟悉websocket的都知道前四个事件(回调函数)是用来处理客户端链接、发送消息、链接关闭以及出错。sessions则是用来管理所有的会话连接。每产生一个连接,都会有一个新Id,sessions中会新增一个IWebSocketSession对象。当页面关闭或者刷新都会触发OnClose,继而sessions中会移除对应的IwebSocketSession对象。

WebSocketSessionManager 有一个广播方法:Sessions.Broadcast,通知所有连接的客户端。而WebSocketBehavior中的Send相当于是单发,只能将消息发送到此刻连接的一个客户端。摸清了以上这些我们就可以做一个简单的IM了。

Websoket.Server

新建一个C#控制台程序。现在Nugget中添加websocket-sharp.以及JSON。

然后新增一个Chat类,继承WebSocketBehavior,Chat相当于是一个websocket的服务,你可以创建多个websocketBehavior的实例然后在挂载在websocketServer上。

 

 public class Chat : WebSocketBehavior{private  Dictionary<string,string> nameList=new Dictionary<string, string>();protected override async Task OnMessage(MessageEventArgs e){StreamReader reader = new StreamReader(e.Data);string text = reader.ReadToEnd();try{var obj = Json.JsonParser.Deserialize<JsonDto>(text);Console.WriteLine("收到消息:" + obj.content + " 类型:" + obj.type + " id:" + Id);switch (obj.type){//正常聊天case "1":obj.name = nameList[Id];await Sessions.Broadcast(Json.JsonParser.Serialize(obj));break;//修改名称case "2":Console.WriteLine("{0}修改名称{1}",nameList[Id],obj.content);Broadcast(string.Format("{0}修改名称{1}", nameList[Id], obj.content),"3");nameList[Id] = obj.content;break;default:await Sessions.Broadcast(text);break;}}catch (Exception exception){Console.WriteLine(exception);}//await Send(text);}protected override async Task OnClose(CloseEventArgs e){Console.WriteLine("连接关闭" + Id);Broadcast(string.Format("{0}下线,共有{1}人在线", nameList[Id], Sessions.Count), "3");nameList.Remove(Id);}protected override async Task OnError(WebSocketSharp.ErrorEventArgs e) {var el = e;}protected override async Task OnOpen(){Console.WriteLine("建立连接"+Id);nameList.Add(Id,"游客"+Sessions.Count);Broadcast(string.Format("{0}上线了,共有{1}人在线", nameList[Id],Sessions.Count), "3");}private void Broadcast(string msg, string type = "1"){var data= new  JsonDto(){content = msg,type = type,name = nameList[Id]};Sessions.Broadcast(Json.JsonParser.Serialize(data));}}

JsonDto

 

    class JsonDto{public string content { get; set; }public string type { get; set; }public string name { get; set; }}

 

这里用nameList来管理所有的链接Id和用户名称的对应关系,新上线的人都默认为游客。然后再OnMessage中定义了三种消息类型。1表示正常聊天,2表示修改名称。3表示系统通知。用来让前端做一些界面上的区分。

然后在Program中启动WebSocketServer。下面指定了8080端口。

 

  public class Program{public static void Main(string[] args){var wssv = new WebSocketServer(null,8080);wssv.AddWebSocketService<Chat>("/Chat");wssv.Start();Console.ReadKey(true);wssv.Stop();}}

 

Client

html:

 <div id="messages"></div><input type="text" id="content" value=""/><button id="sendbt">发送</button><div>昵称:<input type="text" id="nickName"  /> <button id="changebt">修改</button> </div>

js:

 

 function initWS() {ws = new WebSocket("ws://127.0.0.1:8080/Chat");ws.onopen = function (e) {console.log("Openened connection to websocket");console.log(e);};ws.onclose = function () {console.log("Close connection to websocket");// 断线重连initWS();}ws.onmessage = function (e) {console.log("收到",e.data)var div=$("<div>");var data=JSON.parse(e.data);switch(data.type){case "1":div.html(data.name+":"+data.content);break;case "2":div.addClass("gray");div.html("修改名称"+data.content)break;case "3":div.addClass("gray");div.html(data.content)break;}$("#messages").append(div);}}initWS();function sendMsg(msg,type){ws.send(JSON.stringify({content:msg,type:type}));}$("#sendbt").click(function(){var text=$("#content").val();sendMsg(text,"1")$("#content").val("");})$("#changebt").click(function(){var text=$("#nickName").val();sendMsg(text,"2")})

 

运行效果:

是不是很方便~~,喜欢就赞一个。

源码:https://files.cnblogs.com/files/stoneniqiu/websocket-sharp.zip

websocket-sharp:http://sta.github.io/websocket-sharp/

nodejs 实现websocket服务端:http://www.cnblogs.com/stoneniqiu/p/5402311.html 

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

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

相关文章

【转】极限编程一览

极限编程&#xff08;XP&#xff09;起源始于1990年代。当时肯特布莱克&#xff08;Kent Black&#xff09;在戴姆勒克莱斯勒&#xff08;DaimlerChrysler&#xff09;处理项目时&#xff0c;试图寻找一种更好的软件开发方法。他的创立新方法后来被称为极限编程方法论&#xff…

mysql 关联更新_跳出初学MySQL知识的原理整理(一)

一、基础架构MySQL 可以分为 Server 层和存储引擎层两部分。Server 层包括连接器、查询缓存、分析器、优化器、执行器等&#xff0c;所有跨存储引擎的功能都在这一层实现&#xff0c;比如存储过程、触发器、视图等。而存储引擎层负责数据的存储和提取。支持 InnoDB、MyISAM等多…

【转】TcpListener和tcpclient使用

前段时间公司项目中遇着需要做文件的远程传输&#xff0c;场景是用户通过网页选择一些文件&#xff0c;然后提交请求到服务器&#xff0c;同时把请求标识传递给本机的TCP文件传输端&#xff1b;服务器收到请求后在服务器端创建任务生成保存文件的路径同时通知文件传输端开始传文…

sleep期间读取所有_ceph部分数据所有副本先后故障的抢救

半天河网易游戏高级运维工程师&#xff0c;主要负责云存储的运维&#xff1b;一个既希望跟业务聊又喜欢能够默默在后面忙活的普通运维人。背景故障现场故障恢复故障恢复分析第一种方式&#xff1a;物理磁盘对拷第二种方式&#xff1a;服务启动时跳过故障扇区来避免异常退出解决…

【转】有限状态机用法教程

如博文无法正常显示&#xff0c;请访问原文地址&#xff1a; https://blog.csdn.net/ChinarCSDN/article/details/82263126 有限状态机用法教程 文章目录 有限状态机用法教程 [toc]1Finite-state machine —— 有限状态机2Foreword —— 前言()3Example —— 示例4Moltimode —…

通用usb集线器驱动_多口充电、高速传输——ORICO晶锐系列7口集线器测评

随着笔电越来越薄&#xff0c;机身接口数量越来越少&#xff0c;U盘、存储卡、移动硬盘、鼠标、蓝牙适配器等明显感觉无处可插&#xff0c;因此USB集线器就成为笔电的最佳拍档。近期&#xff0c;ORICO(奥睿科)推出了一款晶锐系列7口集线器产品&#xff0c;它集成了7个USB3.0接口…

【转】状态机思路在程序设计中的应用

状态机思路在单片机程序设计中的应用 状态机的概念 状态机是软件编程中的一个重要概念。比这个概念更重要的是对它的灵活应用。在一个思路清晰而且高效的程序中&#xff0c;必然有状态机的身影浮现。 比如说一个按键命令解析程序&#xff0c;就可以被看做状态机&#xff1a;本…

【转】超详细的UML状态图符号,初学者也能轻松看懂状态图

UML状态图&#xff0c;用于显示状态机&#xff0c;即描述一个对象所处的可能状态以及状态之间的转移。用状态图建模可以帮助开发人员分析复杂对象的各种状态的转换&#xff0c;以及对象何时执行怎样的动作。那状态图又是怎样表示这些信息的呢&#xff1f;要想看明白其中的奥妙&…

舒尔特注意力训练表格_舒尔特注意力训练,舒尔特方格练习入口

孩子的注意力是否集中&#xff0c;直接影响孩子的上课效率和作业正确率&#xff0c;最终影响学习成绩。道理大家都懂&#xff0c;关键是如何保证注意力的集中。接下来&#xff0c;我给大家推荐一个简单方便在家就能完成的训练方法&#xff0c;把它比作小游戏也不为过。那就是舒…

nginx文件系统大小_Nginx 了解一下?

这篇文章主要简单的介绍下 Nginx 的相关知识&#xff0c;主要包括以下几部分内容&#xff1a;Nginx 适用于哪些场景&#xff1f;为什么会出现 Nginx&#xff1f;Nginx 优点Nginx 的编译与配置Nginx 适用于哪些场景&#xff1f;如图所示&#xff0c;一个请求会先经过 Nginx 到达…

存储过程排版工具_安利一款比Evernote更为实用的云笔记工具,不容错过

作为一个爱分享的自媒体人&#xff0c;出于工作和兴趣前前后后接触到的云笔记工具很多&#xff0c;例如&#xff1a;有道云笔记、为知笔记、语雀、印象笔记、oneNote...在笔记工具的使用上还是略有点点心得&#xff0c;今天给大家分享一款实用的云笔记工具——Baklib&#xff0…

【转】有限状态机(FSM)学习总结C#

FSM&#xff08;Finite State Machine有限状态机&#xff09;可以理解成是对行为逻辑的抽象&#xff0c;就好象人在生活中会做出各种行为&#xff0c;例如吃饭、睡觉等&#xff0c;这些所有我们都看作是“行为”的分支&#xff0c;由大脑决定每种行为具体是什么实施。在整个FSM…

【转】[完全免费] 在线UML Sequence Diagram 时序图工具 - 教程第3部分

时序图教程 甲序列图描述了一组对象之间的相互作用参与协作&#xff08;或情况&#xff09;&#xff0c;布置成按时间顺序; 它通过它们的“生命线”和它们发送给对方的消息来显示参与交互的对象。 什么是UML中的序列图&#xff1f; UML序列图是详细说明如何执行操作的交互图。…

【转】[完全免费] 在线UML Class Diagram 类图工具 - 教程第1部分

在线Visual Paradigm - UML编辑器 使用在线UML编辑器轻松绘制UML图&#xff0c;其中包含功能强大的UML编辑工具&#xff0c;即时UML语法检查和整洁的用户界面。Visual Paradigm在线UML 图&#xff0c;如类&#xff0c;用例&#xff0c;序列&#xff0c;活动&#xff0c;部署&a…

python 定时器_python 线程之四:定时器(Timer),非阻塞

线程之一讲了线程&#xff0c;如果不熟悉&#xff0c;可以点击【线程之一&#xff1a;线程的创建、启动及运行方式】1、定时器实质&#xff1a;Timer 定时器源码实现&#xff0c;和我们自定义一个线程方式一样&#xff0c;都是继承了 Thread 类&#xff0c;重写了 run() 方法&a…

人如何认知事物?

自然界是连续的&#xff0c;人类将自然界离散化成一个个独立的概念&#xff0c;独立的概念相互关联&#xff0c;形成模型&#xff0c;随着模型的完善&#xff0c;模型会不断逼近真实事物。 比如人类创造了各种学科&#xff0c;就是从不同的方面深入研究世界的结果。 所以&…

域内定位个人PC的三种方式(1)

会话搜集 在cmd下调用query session命令可以获得当前环境下的windows会话 NetSessionEnum 这个函数不允许直接查询是谁登陆&#xff0c;但是它允许查询是谁在访问此工作站的网络资源时所创建的网络会话&#xff0c;从而知道来自何处&#xff0c;此函数不需要高权限即可查询 第…

02.Teams组成概述及使用分享

在上一篇博客中介绍了Teams的前世今生&#xff0c;大家对Teams已经有了一个初步的认识&#xff0c;但是如上一篇文章中所说Teams是一个集成度很高的云协作平台&#xff0c;具体应该怎么去有效的利用起来呢&#xff1f;接下来这篇博客给大家全方位的分享一下Teams的组成部分以及…

【Qt】解决GDAL直接读取数据到QImage导致图像歪斜的问题

QRect intersect_rect; .... QImage img(intersect_rect.size(), QImage::Format_RGB888); uchar *pImageData (unsigned char *)img.constBits(); int img_width intersect_rect.width(); int img_height intersect_rect.height();// QImage每行是按照sizeof(int)对齐的&am…

高斯课堂数电讲义笔记_【法考经验贴】40岁三战主观题127分!他的笔记学习法助他逆袭!...

这位学员在考证界算是“高龄学员”&#xff0c;高分过关依赖于他的努力和正确的学习方法&#xff1b;本文中他有重点介绍自己是如何做笔记的&#xff0c;非常值得大家学习借鉴&#xff01;一、个人概况&#xff1a;三战法考我正值不惑之年&#xff0c;是一名在职基层人民警察&a…