• .net 长连接,实现服务器推送(server push)


    服务端:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading;
    using System.Web;
    
    namespace WebApplication2
    {
        public class MyHandler : IHttpHandler
        {
            /// <summary>
            /// 消息下发请求
            /// </summary>
            /// <param name="context"></param>
            public void ProcessRequest(HttpContext context)
            {
                //不让客户端缓存
                context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    
                List<MyAsyncResult> userlist = MyAsyncHandler.Queue;
                
                //唯一标识
                string sessionId = context.Request.QueryString["sessionId"];
    
                //消息内容
                string message = context.Request.QueryString["message"] + "    " + userlist.Count.ToString();
    
                List<string> error = new List<string>();
    
                foreach (MyAsyncResult res in userlist)
                {
    
                    //如果不是自己就推送信息
                    if (res.SessionId != sessionId)
                    {
    
                        res.Message = message;
                        try
                        {
                            //推送内容
                            res.SetCompleted(true);
                        }
                        catch (Exception)
                        {
                            //如果推送失败(客户端已断开,网络异常等)
                            //则删除该标志
                            error.Add(res.SessionId);
                        }
    
                    }
    
                }
    
                foreach (var v in error)
                {
                    userlist.RemoveAll(fun => fun.SessionId == v);
                }
    
            }
    
            public bool IsReusable
            {
                get { return true; }
            }
        }
    
        public class MyAsyncHandler : IHttpAsyncHandler
        {
            public static List<MyAsyncResult> Queue = new List<MyAsyncResult>();
    
            public void ProcessRequest(HttpContext context)
            {
            }
    
            public bool IsReusable
            {
                get { return true; }
            }
    
            public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
            {
                //接到连接请求
    
                //不让客户端缓存
                context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    
                //获取唯一标识
                string sessionId = context.Request.QueryString["sessionId"];
    
                if (Queue.Count(fun => fun.SessionId == sessionId) > 0)
                {
                    int index = Queue.IndexOf(Queue.Find(fun => fun.SessionId == sessionId));
                    Queue[index].Context = context;
                    Queue[index].CallBack = cb;
                    return Queue[index];
                }
    
                //如果不存在则加入队列
                MyAsyncResult asyncResult = new MyAsyncResult(context, cb, sessionId);
                Queue.Add(asyncResult);
                return asyncResult;
            }
    
            public void EndProcessRequest(IAsyncResult result)
            {
                //长连接结束前写入内容
                MyAsyncResult rslt = (MyAsyncResult)result;
                
                //拼装返回内容
                rslt.Context.Response.Write(rslt.Message);
                rslt.Message = string.Empty;
            }
        }
    
    
        public class MyAsyncResult : IAsyncResult
        {
            /// <summary>
            /// 是否结束请求
            /// true:完成
            /// false:阻塞
            /// </summary>
            public bool IsCompleted
            {
                get;
                private set;
            }
    
            public WaitHandle AsyncWaitHandle
            {
                get;
                private set;
            }
    
            public object AsyncState
            {
                get;
                private set;
            }
    
            public bool CompletedSynchronously
            {
                get { return false; }
            }
    
            public HttpContext Context { get; set; }
            public AsyncCallback CallBack { get; set; }
    
            /// <summary>
            /// 自定义标识
            /// </summary>
            public string SessionId { get; set; }
    
            /// <summary>
            /// 自定义消息
            /// </summary>
            public string Message { get; set; }
    
            public MyAsyncResult(HttpContext context, AsyncCallback cb, string sessionId)
            {
                this.SessionId = sessionId;
                this.Context = context;
                this.CallBack = cb;
                IsCompleted = true;
            }
    
            /// <summary>
            /// 发送消息
            /// </summary>
            /// <param name="iscompleted">确认下发信息</param>
            public void SetCompleted(bool iscompleted)
            {
                if (iscompleted && this.CallBack != null)
                {
                    CallBack(this);
                }
            }
        }
    }
    

     客户端:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
    </head>
    <body>
        <input type="text" id="sessionId" /><input type="button" value="进入" onclick="comin()" /><br />
        <input type="text" id="message" /><input type="button" value="发送" onclick="send()" />
        <div id="messages">
        </div>
        <script type="text/javascript">
    
            function comin() {
    
                var xmlHttp = ajaxFunction();
    
                var url = "MyAsyncHandler.ashx?sessionId=" + document.getElementById("sessionId").value;
    
                xmlHttp.onreadystatechange = function () {
    
                    if (xmlHttp.readyState == 4) {
    
                        if (xmlHttp.status == 200) {
    
                            document.getElementById("messages").innerHTML += xmlHttp.responseText + "<br>";
    
                            //连接已经结束,马上开启另外一个连接 
    
                            comin();
    
                        }
    
                    }
    
                }
    
                xmlHttp.open("get", url, true);
    
                xmlHttp.send(null);
    
            }
    
    
            function send() {
    
                var xmlHttp = ajaxFunction();
    
                var url = "MyHandler.ashx?sessionId=" + document.getElementById("sessionId").value + "&message=" + document.getElementById("message").value;
    
    
                xmlHttp.onreadystatechange = function () {
    
                    if (xmlHttp.readyState == 4) {
    
                        if (xmlHttp.status == 200) {
                            
                        }
                        else {
    
                            alert("错误:" + xmlHttp.status);
    
                        }
    
                    }
                }
    
                xmlHttp.open("get", url, true);
    
                xmlHttp.send(null);
    
            }
    
            function ajaxFunction() {
    
                var xmlHttp;
    
                try {
    
                    xmlHttp = new XMLHttpRequest();
    
                }
    
                catch (e) {
    
                    try {
    
                        xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
    
                    }
    
                    catch (e) {
    
                        try {
    
                            xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    
                        }
    
                        catch (e) {
    
                            alert("您的浏览器不支持AJAX!");
    
                            return false;
    
                        }
    
                    }
    
                }
    
                return xmlHttp;
    
            } 
    
        </script>
    </body>
    </html>
    

     配置文件:

    web.Config
     <httpHandlers>
          <add verb="*" path="MyHandler.ashx" type="WebApplication2.MyHandler"/>
    
          <add verb="*" path="MyAsyncHandler.ashx" type="WebApplication2.MyAsyncHandler"/>
    
     </httpHandlers>

     以上代码均测试通过。

    摘自:http://blog.chinaunix.net/uid-27875-id-3118211.html

  • 相关阅读:
    Oracle 的日期类型
    简单的同步Socket程序服务端
    MMORPG中的相机跟随算法
    使用了UnityEditor中的API,打包时却不能打包UnityEditor的问题
    C# 中的关键字整理
    Unity3D C#中使用LINQ查询(与 SQL的区别)
    C# 值类型与引用类型的异同
    Unity3D NGUI事件监听的综合管理
    Unity3D 动画状态机简单控制核心代码
    Unity3D判断触摸方向
  • 原文地址:https://www.cnblogs.com/comsokey/p/ServicePush.html
Copyright © 2020-2023  润新知