HTML5-WebSocket实现聊天室
在传统的网页实现聊天室的方法是通过每隔一段时间请求服务器获取相关聊天信息来实现,然而html5带来的websocket功能改变这了这种方式.由于websocket在连接服务器后允许保持连接来进行数据交互,因此服务器可以主动地向客户端发送相应的数据.对于html5的处理只需要在连接创建完成后在websocket的receive事件中处理接收的数据即可.下面通过实现一个聊天室来体验一下服务器可以主动地向客户端发的功能.
功能
一个简单的聊天室主要有以下几个功能:
1)注册
注册要处理几个事情,分别是注册完成后获取当前服务器所有用户列表,服务把当前注册成功的用户发送给其他在线的用户.
2)发信息
服务器把当前接收的消息发送给在线的其他用户
3)退出
服务器把断开的用户通知其他用户
聊天室完成的功能预览如下:
C#服务端代码
服务端的代码只需要针对几功能定义几个方法即可,分别是注册,获取其他用户和发送信息.具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | /// <summary> /// Copyright © henryfan 2012 ///Email: henryfan@msn.com ///HomePage: http://www.ikende.com ///CreateTime: 2012/12/7 21:45:25 /// </summary> class Handler { public long Register( string name) { TcpChannel channel = MethodContext.Current.Channel; Console.WriteLine( "{0} register name:{1}" , channel.EndPoint, name); channel.Name = name; JsonMessage msg = new JsonMessage(); User user = new User(); user.Name = name; user.ID = channel.ClientID; user.IP = channel.EndPoint.ToString(); channel.Tag = user; msg.type = "register" ; msg.data = user; foreach (TcpChannel item in channel.Server.GetOnlines()) { if (item != channel) item.Send(msg); } return channel.ClientID; } public IList<User> List() { TcpChannel channel = MethodContext.Current.Channel; IList<User> result = new List<User>(); foreach (TcpChannel item in channel.Server.GetOnlines()) { if (item != channel) result.Add((User)item.Tag); } return result; } public void Say( string Content) { TcpChannel channel = MethodContext.Current.Channel; JsonMessage msg = new JsonMessage(); SayText st = new SayText(); st.Name = channel.Name; st.ID = channel.ClientID; st.Date = DateTime.Now; st.Content = Content; st.IP = channel.EndPoint.ToString(); msg.type = "say" ; msg.data = st; foreach (TcpChannel item in channel.Server.GetOnlines()) { item.Send(msg); } } } |
只需要以上简单的代码就完成了聊天室服务端的功能,对于用户退出可以通过连接释放事件来做处理具体代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | protected override void OnDisposed( object sender, ChannelDisposedEventArgs e) { base .OnDisposed(sender, e); Console.WriteLine( "{0} disposed" , e.Channel.EndPoint); JsonMessage msg = new JsonMessage(); User user = new User(); user.Name = e.Channel.Name; user.ID = e.Channel.ClientID; user.IP = e.Channel.EndPoint.ToString(); msg.type = "unregister" ; msg.data = (User)e.Channel.Tag; foreach (TcpChannel item in this .Server.GetOnlines()) { if (item != e.Channel) item.Send(msg); } } |
这样聊天定的服务端代码就已经完成了.
JavaScript代码
对于html5代码首先要做的一件事就是连接到服务器,相关javascript代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | function connect() { channel = new TcpChannel(); channel.Connected = function (evt) { callRegister.parameters.name = $( '#nikename' ).val(); channel.Send(callRegister, function (result) { if (result.status == null || result.status == undefined) { $( '#dlgConnect' ).dialog( 'close' ); registerid = result.data; list(); } }); }; channel.Disposed = function (evt) { $( '#dlgConnect' ).dialog( 'open' ); }; channel.Error = function (evt) { alert(evt); }; channel.Receive = function (result) { if (result.type == "register" ) { var item = getUser(result.data); $(item).appendTo($( '#lstOnlines' )); } else if (result.type == 'unregister' ) { $( '#user_' + result.data.ID).remove(); } else if (result.type == 'say' ) { addSayItem(result.data); } else { } } channel.Connect($( '#host' ).val()); } |
通过Receive回调池数来处理不同消息的情况,如果是接收到其他用户的注册信息,则把用户信息添加到列表中;如果收到的其他用户的退出信息则在用户列表种移走;直接收到消息添加到消息显示框中即可.有jquery的帮助以上事件都变得非常简单.
用户注册调用过程:
1 2 3 4 5 6 7 8 9 10 11 12 | var callRegister = { url: 'Handler.Register' , parameters: { name: '' } }; function register() { $( '#frmRegister' ).form( 'submit' , { onSubmit: function () { var isValid = $( this ).form( 'validate' ); if (isValid) { connect(); } return false ; } }); } |
获取在线用户列表过程:
1 2 3 4 5 6 7 8 9 10 | var callList = { url: 'Handler.List' , parameters: {} }; function list() { channel.Send(callList, function (result) { $( '#lstOnlines' ).html( '' ); for ( var i = 0; i < result.data.length; i++) { var item = getUser(result.data[i]); $(item).appendTo($( '#lstOnlines' )); } }); } |
发送消息过程:
1 2 3 4 5 6 7 | var callSay = { url: 'Handler.Say' , parameters: {Content: "" } } function Say() { callSay.parameters.Content = mEditor.html(); mEditor.html( '' ); channel.Send(callSay); $( '#content1' )[0].focus(); } |
总结
经过代码封装后websocket的处理变得非常简单,如果你有兴趣完全可以在此代码上扩展出一个更多功能的聊到室,如聊天室分组,发送信息图片共享等等.
演示地址:http://html5.ikende.com/chatroom.htm
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架