zoukankan      html  css  js  c++  java
  • .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

  • 相关阅读:
    Mvc+三层(批量添加、删除、修改)
    js中判断复选款是否选中
    EF的优缺点
    Git tricks: Unstaging files
    Using Git Submodules
    English Learning
    wix xslt for adding node
    The breakpoint will not currently be hit. No symbols have been loaded for this document."
    Use XSLT in wix
    mfc110ud.dll not found
  • 原文地址:https://www.cnblogs.com/comsokey/p/ServicePush.html
Copyright © 2011-2022 走看看