comet 推送消息到客户端

weiconfig:

1   <system.web>
2     <httpHandlers>
3       <add path="comet_broadcast.ashx" type="AsnyHandler" verb="POST,GET"/>
4     </httpHandlers>
5     <compilation debug="true" targetFramework="4.0"/>
6     <httpRuntime/>
7   </system.web>
View Code

一般处理程序Handler1

 1  public class Handler1 : IHttpHandler
 2     {
 3 
 4         public void ProcessRequest(HttpContext context)
 5         {
 6             context.Response.ContentType = "text/plain";
 7             context.Response.Write("Hello World:" + DateTime.Now.ToString("HH:mm:ss"));//需要输出特定的信息的,可以在这里处理,例如读取数据库的最新参数啊,获取memcached的值之类的都行.
 8         }
 9 
10         public bool IsReusable
11         {
12             get
13             {
14                 return false;
15             }
16         }
17     }
View Code

页面:

 1 <html xmlns="http://www.w3.org/1999/xhtml">
 2 <head runat="server">
 3     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 4     <title></title>
 5     <style type="text/css">
 6         * {
 7             font-size: 12px;
 8         }
 9 
10         #divResult {
11             border: 1px solid #000;
12              250px;
13         }
14     </style>
15     <script src="Scripts/jquery-1.3.2.min.js"></script>
16     <script type="text/javascript">
17         function fUpdateData(data) {
18          
19             $.post("comet_broadcast.ashx", { content: data },
20                 function (data, status) {
21                     alert(data);
22                     var result = $("#divResult");
23                     result.html(result.html() + "<br/>" + data);
24                     //                    $("#divResult").html(data);
25                     //服务器返回消息,再次请求后台数据
26                     fGetData();
27                 }, "html"
28          );
29         }
30         //获取服务器最新信息
31         function fGetData() {
32             $.ajax({
33                 type: 'GET',
34                 url: 'Handler1.ashx',
35                 success: function (data) {
36 
37                     fUpdateData(data);
38                 }
39             });
40         }
41         $(document).ready(function () {
42             //初始化
43             fGetData();
44         });
45     </script>
46 </head>
47 <body>
48     <form id="form1" runat="server">
49         <div>
50             后台推送最新消息:
51         <div id="divResult">
52         </div>
53         </div>
54     </form>
55 </body>
56 </html>
View Code

AsnyHandler类与 myAsynResult类:

 1 public class AsnyHandler:IHttpAsyncHandler
 2 {
 3     public AsnyHandler()
 4     {
 5     }
 6 
 7     public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
 8     {
 9         //myAsynResult为实现了IAsyncResult接口的类,当不调用cb的回调函数时,该请求不会返回到给客户端,会一直处于连接状态
10         myAsynResult asyncResult = new myAsynResult(context, cb, extraData);
11         String content = context.Request.Params["content"];
12 
13         //向Message类中添加该消息
14         Messages.Instance().AddMessage(content, asyncResult);
15         return asyncResult;
16     }
17 
18     #region 不必理会
19     
20     public void EndProcessRequest(IAsyncResult result)
21     {
22       
23     }
24 
25     public bool IsReusable
26     {
27         get { return false; ; }
28     }
29 
30     public void ProcessRequest(HttpContext context)
31     {
32     }
33     #endregion
34 }
35 public class myAsynResult : IAsyncResult
36 {
37     bool _IsCompleted = false;
38     private HttpContext context;
39     private AsyncCallback cb;
40     private object extraData;
41     public myAsynResult(HttpContext context, AsyncCallback cb, object extraData)
42     {
43         this.context = context;
44         this.cb = cb;
45         this.extraData = extraData;
46     }
47     private string _content;
48     public string Content { 
49         get {return _content;}
50         set{_content=value;} 
51     }
52 
53     #region IAsyncResult接口
54     public object AsyncState
55     {
56         get { return null; }
57     }
58 
59     public System.Threading.WaitHandle AsyncWaitHandle
60     {
61         get { return null; }
62     }
63 
64     public bool CompletedSynchronously
65     {
66         get { return false; }
67     }
68     public bool IsCompleted
69     {
70         get { return _IsCompleted; }
71     }
72     #endregion
73 
74     //在Message类中的添加消息方法中,调用该方法,将消息输入到客户端,从而实现广播的功能
75     public void Send(object data)
76     {
77             context.Response.Write(this.Content);
78             if (cb!=null)
79             {
80                 cb(this);
81             }
82             _IsCompleted = true; ;
83     }
84 }
View Code

Messages类:

 1 public class Messages
 2 {
 3     //记录所有请求的客户端
 4     List<myAsynResult> clients = new List<myAsynResult>();
 5 
 6     #region 实现该类的单例
 7     private static readonly Messages _Instance = new Messages();
 8     private Messages()
 9     {
10     }
11     public static Messages Instance()
12     {
13         return _Instance;
14     }
15     #endregion
16 
17     public void AddMessage(string content,myAsynResult asyncResult)
18     {
19         //当传入的内容为"-1"时,表示为建立连接请求,即为了维持一个从客户端到服务器的连接而建立的连接
20         //此时将该连接保存到 List<myAsynResult> clients中,待再有消息发送过来时,该连接将会被遍历,并且会将该连接输出内容后,结束该连接
21         if (content=="-1")
22         {
23             clients.Add(asyncResult);
24         }
25         else
26         {
27             //将当前请求的内容输出到客户端
28             asyncResult.Content = content;
29             asyncResult.Send(null);
30 
31             //否则将遍历所有已缓存的client,并将当前内容输出到客户端
32             foreach (myAsynResult result in clients)
33             {
34                 result.Content = content;
35                 result.Send(null);
36             }
37 
38             //清空所有缓存
39             clients.Clear();
40         }
41     }
42 }
View Code
原文地址:https://www.cnblogs.com/jbps/p/4838559.html