博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET WebForm(MVC)下实现消息推送(提供简单Demo下载)
阅读量:5028 次
发布时间:2019-06-12

本文共 14559 字,大约阅读时间需要 48 分钟。

由于项目需要,笔者最近需要实现Web客户端之间的消息的即时推送功能。

功能描述如下:

假设A,B,C用户登陆,内存记录下已登录的用户的信息,这时A在所在的客户端(SendInfo.aspx)页面向B发消息,则在B所在客户端页面(SendInfo.aspx)将弹出消息框。

关键点有两个:

1.保证客户端和服务端的连接

2.保证服务端能够向客户端广播消息

笔者是第一次做这样的实现,所以Google了一些资料,了解到可使用Comet,ajax轮询,WebSocket等技术实现,

由于时间关系,发现有些技术不是很容易理解,这里做了一个简单Demo.希望能够达到抛砖引玉的作用,与大家分享,共同提高。

笔者做了两个框架下的实现,ASP.NET Web Form和ASP.NET MVC 下的尝试。

ASP.NET Web Form版:

AsyncHandler.cs

View Code
using System;using System.Collections.Generic;using System.Web;using System.Threading;namespace CometSample{    public class WebIMAsyncHandler : IHttpAsyncHandler    {        #region IHttpAsyncHandler 成员        public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)        {            string _UID = context.Request.Params["uid"];            WebIMClientAsyncResult _AsyncResult = new WebIMClientAsyncResult(context, cb, extraData);            string _Content = context.Request.Params["content"];            string _Action = context.Request.Params["action"];            if (_Action == "login")            {                _UID = context.Request.Params["uid"];                _AsyncResult.LoginID = _UID;                WebIMMessageHandler.Instance().Login(_UID, _AsyncResult);            }            else if (_Action == "logout")            {                _AsyncResult.LoginID = _UID;                WebIMMessageHandler.Instance().Logout(_UID, _AsyncResult);            }            else if (_Action == "connect")            {                _AsyncResult.LoginID = _UID;                WebIMMessageHandler.Instance().Connect(_AsyncResult);            }            else if (_Action == "getuserlist")            {                _AsyncResult.LoginID = _UID;                WebIMMessageHandler.Instance().GetUserList(_AsyncResult);            }            //增加消息发送            else if (_Action == "sendmsg")            {                _AsyncResult.LoginID = _UID;                //WebIMMessageHandler.Instance().GetUserList(_AsyncResult);                //调用                WebIMMessageHandler.Instance().AddMessage(_Content, _AsyncResult);            }            //调用            //WebIMMessageHandler.Instance().AddMessage(_Content, _AsyncResult);            return _AsyncResult;        }        public void EndProcessRequest(IAsyncResult result)        {        }        #endregion        #region IHttpHandler 成员        public bool IsReusable        {            get { return false; ; }        }        public void ProcessRequest(HttpContext context)        {            throw new NotImplementedException();        }        #endregion    }    public class WebIMClientAsyncResult : IAsyncResult    {        bool m_IsCompleted = false;        private HttpContext m_Context;        private AsyncCallback m_Callback;        private object m_ExtraData;        private string m_Content;        private string m_LoginID = string.Empty;        public WebIMClientAsyncResult(HttpContext p_Context, AsyncCallback p_Callback, object p_ExtraData)        {            this.m_Context = p_Context;            this.m_Callback = p_Callback;            this.m_ExtraData = p_ExtraData;        }        ///         /// 用户编号        ///         public string LoginID        {            get            {                return m_LoginID;            }            set            {                m_LoginID = value;            }        }        ///         /// 发送消息的内容,暂时未使用到        ///         public string Content        {            get            {                return m_Content;            }            set            {                m_Content = value;            }        }        #region IAsyncResult 成员        public object AsyncState        {            get { return null; }        }        public WaitHandle AsyncWaitHandle        {            get { return null; }        }        public bool CompletedSynchronously        {            get { return false; }        }        public bool IsCompleted        {            get { return m_IsCompleted; }        }        #endregion        ///         /// 向客户端响应消息        ///         ///         public void Send(object data)        {            try            {                m_Context.Response.Write(this.Content);                if (m_Callback != null)                {                    m_Callback(this);                }                            }            catch { }            finally             {                m_IsCompleted = true;             }        }    }}

MessageHandler.cs

View Code
using System;using System.Collections;using System.Collections.Generic;using System.Web;using System.Text;namespace CometSample{    public class WebIMMessageHandler    {        private static readonly WebIMMessageHandler m_Instance = new WebIMMessageHandler();                //记录所有请求的客户端        List
m_Clients = new List
(); //Dictionary
m_Clients=new Dictionary
(); string m_Users = string.Empty; public WebIMMessageHandler() { } public static WebIMMessageHandler Instance() { return m_Instance; } ///
/// 登录 /// ///
///
public void Login(string p_LoginID, WebIMClientAsyncResult p_ClientAsyncResult) { bool _Logined = false; foreach (WebIMClientAsyncResult _Item in m_Clients) { if (_Item.LoginID == p_LoginID) { p_ClientAsyncResult.Content = "你已登录"; _Logined = true; break; } } if (!_Logined) { //m_Clients.Add(p_ClientAsyncResult); p_ClientAsyncResult.Content = "OK"; } p_ClientAsyncResult.Send(null); } private string GetUsers() { /* string _Users = string.Empty; foreach (WebIMClientAsyncResult _Item in m_Clients) { _Users += _Item.LoginID + ","; } return _Users; */ var sbUsers = new StringBuilder(); sbUsers.Append("Users:"); foreach (WebIMClientAsyncResult _Item in m_Clients) { sbUsers.Append(_Item.LoginID); sbUsers.Append(","); } return sbUsers.ToString(); } public void Logout(string p_LoginID, WebIMClientAsyncResult p_ClientAsyncResult) { foreach (WebIMClientAsyncResult _Item in m_Clients) { if (_Item.LoginID == p_LoginID) { m_Clients.Remove(_Item); break; } } p_ClientAsyncResult.Content = "退出成功"; p_ClientAsyncResult.Send(null); //UpdateUserList(); string _Users = GetUsers(); foreach (WebIMClientAsyncResult _Item in m_Clients) { _Item.Content = _Users; _Item.Send(null); } m_Clients.Clear(); } public void GetUserList(WebIMClientAsyncResult p_ClientAsyncResult) { Connect(p_ClientAsyncResult); string _Users = GetUsers(); foreach (WebIMClientAsyncResult _Item in m_Clients) { _Item.Content = _Users; _Item.Send(null); } m_Clients.Clear(); } public void Connect(WebIMClientAsyncResult p_Client) { bool _Exists = false; foreach (WebIMClientAsyncResult _Item in m_Clients) { if (_Item.LoginID == p_Client.LoginID) { _Exists = true; break; } } if (!_Exists) { m_Clients.Add(p_Client); } } /* public void UpdateUserList() { string _Users = GetUsers(); foreach (WebIMClientAsyncResult result in m_Clients) { result.Content = m_Users; result.Send(null); } m_Clients.Clear(); }*/ ///
/// 广播消息 /// ///
///
public void AddMessage(string p_Message, WebIMClientAsyncResult p_ClientAsyncResult) { //保持连接 if (p_Message == "-1") { m_Clients.Add(p_ClientAsyncResult); } else { //将当前请求的内容输出到客户端 p_ClientAsyncResult.Content = p_Message; p_ClientAsyncResult.Send(null); //否则将遍历所有已缓存的client,并将当前内容输出到客户端 foreach (WebIMClientAsyncResult result in m_Clients) { //发送给所有已经登录用户 var strMsg = string.Format("{0}{1}{2}{3}{4}",p_ClientAsyncResult.LoginID,"发送给",result.LoginID,"的消息:",p_Message); //result.Content = p_Message; result.Content = strMsg; result.Send(null); //发送给指定用户 /* if (string.Equals(result.LoginID, "ZhangShan") && !string.Equals(p_ClientAsyncResult.LoginID, "ZhangShan")) { var strMsg = string.Format("{0}{1}{2}{3}{4}{5}","Msgs:", p_ClientAsyncResult.LoginID, "发送给", result.LoginID, "的消息:", p_Message); //result.Content = p_Message; result.Content = strMsg; result.Send(null); } */ } //清空所有缓存 m_Clients.Clear(); } } }}

Login.js

View Code
/// 
$(document).ready(function () { //登录,登录成功后,获取在线用户列表, function login() { //增加页面跳转 var strUrl = '/SendInfo.aspx?strUid=' + $("#txtLoginID").val(); window.open(strUrl); } $("#btnLogin").click(function () { if ($("#txtLoginID").val() == '') alert('空'); login(); });})

WebIM.js

View Code
/// 
//$(document).ready(function () {
//状态,代表是否登录 //var _logined = false; //登录,登录成功后,获取在线用户列表, function login() { //$.post("comet_broadcast.asyn", { action: 'login', uid: $("#txtLoginID").val() }, $.post("comet_broadcast.asyn", { action: 'login', uid: strUid }, function (data, status) { if (data == "OK") { _logined = true; getuserlist(); //增加页面跳转 /*var strUrl = '\SendInfo.aspx?strUid=' + $("#txtLoginID").val(); window.open(strUrl); */ } else { alert(data); } }); } //获取在线用户列表,获取列表后,进入消息等待 function getuserlist() { //$.post("comet_broadcast.asyn", { action: 'getuserlist', uid: $("#txtLoginID").val() }, $.post("comet_broadcast.asyn", { action: 'getuserlist', uid: strUid }, function (data, status) { //alert('getuserlist' + data); var result = $("#divResult"); result.html(result.html() + "
" + "用户列表:" + data); wait(); }); } //退出 function logout() { //$.post("comet_broadcast.asyn", { action: 'logout', uid: $("#txtLoginID").val() }, $.post("comet_broadcast.asyn", { action: 'logout', uid: strUid }, function (data, status) { _logined = false; alert(data); } ); } //消息等待,接收到消息后显示,发起下一次的消息等待 function wait() { //$.post("comet_broadcast.asyn", { action: 'connect', uid: $("#txtLoginID").val() }, $.post("comet_broadcast.asyn", { action: 'connect', uid: strUid }, function (data, status) { /* var result = $("#divResult"); result.html(result.html() + "
" + "用户列表:" + data); */ //2.窗口 new Ext.ux.ToastWindow({ title: '提示窗口', html: data, iconCls: 'error' }).show(document); //服务器返回消息,再次建立连接 if (_logined) { wait(); } }, "html"); } /*********** *********************消息发送部分*************************** ************/ function send() { //$.post("comet_broadcast.asyn", { action: 'sendmsg', uid: $("#txtLoginID").val(), content: $("#content").val() }, $.post("comet_broadcast.asyn", { action: 'sendmsg', uid: strUid, content: $("#content").val() }, function (data, status) { /* var result = $("#divResult"); result.html(result.html() + "
" + "已发消息:" + data); */ //发送方页面提示 //潜规则:暂时不处理 /* //2.窗口 new Ext.ux.ToastWindow({ title: '提示窗口', html: data, iconCls: 'error' }).show(document); */ }, "html" ); //向comet_broadcast.asyn发送请求,消息体为文本框content中的内容,请求接收类为AsnyHandler //$.post("comet_broadcast.asyn", { content: $("#content").val() }); //清空内容 $("#content").val(""); }; /** * 获取字符串中某个特殊字符首次出现的位置之前的子串 */ function GetSubStrBySpecChar(strConnStr,strSplit){ var arrStr = strConnStr.split(strSplit); var strSubStr = arrStr[0]; return strSubStr; }

Default.aspx

View Code
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="CometSample._Default" %>                

SendInfo.aspx

View Code
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SendInfo.aspx.cs" Inherits="CometSample.SendInfo" %>    SendInfo            
广播内容:
消息记录:

最后还需要关注的是配置文件中的路径

在web.config 文件的system.web之间加上

 

好了运行程序,

效果如下:

登陆之后,跳转到sendinfo页面

 

笔者打开连个浏览器,模拟两个客户端登陆,并且模拟广播消息(能够广播,那么向指定客户端发消息也就很容易了)

我们可以看到在页面右下角,有消息弹出

在.NET WebForm下笔者实现了客户端之间即时消息的推送,

但是在.NET MVC 2 下遇到了一些问题,因为mvc框架下对 ,NET WebForm中某些东西不支持。

各位看官,若有在MVC2下的实现,多多交流和分享哈! 

源码下载

 

转载于:https://www.cnblogs.com/lucky_hu/archive/2013/03/12/2954989.html

你可能感兴趣的文章
php面向对象编程(oop)基础知识示例解释
查看>>
1.在数组中找到与给定总和的配对
查看>>
树的子结构
查看>>
关于根据Build Platform或者OS 加载x86或者x64 dll的问题
查看>>
程序员高效开发的几个技巧
查看>>
js-权威指南学习笔记19.2
查看>>
hexo 搭建博客
查看>>
关于 UIWebView 几个高级用法
查看>>
maven创建的项目中无法创建src/main/java 解决方案
查看>>
华为软件开发云测评报告二:代码检查
查看>>
集合1
查看>>
js 原生 ajax
查看>>
关键词 virtual
查看>>
建造者模式(屌丝专用)
查看>>
UVALive 4730 Kingdom +段树和支票托收
查看>>
[APIO2010]特别行动队
查看>>
[SCOI2016]幸运数字
查看>>
SpringBoot 集成ehcache
查看>>
初步swift语言学习笔记2(可选类型?和隐式可选类型!)
查看>>
Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点
查看>>