c# mvc 服务器推

    <script type="text/javascript">
        function Keepline() {
            var da = { Action: "Keepline",userId:$("#userid").val() };
            $.ajax({
                type: 'POST',
                url: "@Url.Content("~")comet_broadcast.asyn",
                data: da,
                dataType: 'json',
                success: function (data, status) {
                    //debugger;
                    //if (data.ResponseStatus == 1) {
                    //    alert(1);
                    //}
                    $("#maxPrice").html(data);
                    Keepline();
                },
                error: function (XMLHttpRequest, errorinfo, er) {
               // debugger;
                    // alert(2);
                },
                complete: function (XHR, TS) {
                    //debugger;
                    //alert(3);
                }
            });
        }


        function BaoJia() {
            var sData = { Action: "GetMaxBaoJia", userId: $("#userid").val(), price: $("#txt_price").val() };
            $.ajax({
                type: 'POST',
                url: "@Url.Content("~")comet_broadcast.asyn",
                data: sData,
                dataType: 'json',
                success: function (data, status) {
                    $("#maxPrice").html(data);
                },
                error: function (XMLHttpRequest, errorinfo, er) {
                    //debugger;
                   // alert(2);
                },
                complete: function (XHR, TS) {
                    //debugger;
                    //alert(3);
                }

            });
        }

    </script>

<body>
    先加入后再报价<br />
               用户: <input type="text" id="userid"/>  <input type="button"  value="加入" οnclick="Keepline()" /><br />
                <input type="button"  value="报价" οnclick="BaoJia()" /><br />          
                <input type="text" id="txt_price"/><br />
                当前最高报价:   <div id="maxPrice">0</div>
</body>
</html>

system.web下 加配置

    <httpHandlers>
      <!--comet长连接配置字节-->
      <add verb="*" path="comet_broadcast.asyn" type="ServerPushHttpHandler.ServerPush,ServerPushHttpHandler"/>
    </httpHandlers>


RouteConfig 中加

            routes.IgnoreRoute("{resource}.asyn/{*pathInfo}");


        /// <summary>
        /// 演示服务推送的界面
        /// </summary>
        /// <returns></returns>
        public ActionResult Demo_Server_Push()
        {
            return View();
        }


新增一个类库 ServerPushHttpHandler

新增三个类

    public class ServerPush : IHttpAsyncHandler
    {
        #region IHttpAsyncHandler 成员
        //启用对HTTP处理程序的异步调用
        public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
        {
            return new ServerPushHandler(context, new ServerPushResult(context, cb, extraData)).ExecAction();
        }

        //进程结束时提供异步处理 End 方法。
        public void EndProcessRequest(IAsyncResult result)
        {

        }
        #endregion

        #region IHttpHandler 成员(IHttpAsyncHandler同时继承于IHttpHandler)
        //获取一个值,该值指示其他请求是否可以使用 IHttpHandler 实例。 (继承自 IHttpHandler。)
        public bool IsReusable
        {
            get { return false; ; }
        }

        //通过实现 IHttpHandler 接口的自定义 HttpHandler 启用 HTTP Web 请求的处理。 (继承自 IHttpHandler。)
        public void ProcessRequest(HttpContext context)
        {
            throw new NotImplementedException();
        }
        #endregion
    }


    public class ServerPushHandler
    {
        #region 全局变量
        HttpContext m_Context;
        //推送结果
        ServerPushResult _IAsyncResult;
        //声明一个集合
        static Dictionary<string, ServerPushResult> dict = new Dictionary<string, ServerPushResult>();

        static int tempMaxBaoJia=0;//临时最高报价
       
        #endregion

        #region 构造函数
        /// <summary>
        /// 构造方法
        /// </summary>
        public ServerPushHandler(HttpContext context, ServerPushResult _IAsyncResult)
        {
            this.m_Context = context;
            this._IAsyncResult = _IAsyncResult;
        }
        #endregion

        #region 执行操作
        /// <summary>
        /// 根据Action判断执行方法
        /// </summary>
        /// <returns></returns>
        public ServerPushResult ExecAction()
        {
            var userid = m_Context.Request["userId"];
            switch (m_Context.Request["Action"])
            {
                case "GetMaxBaoJia":
                    var price =Convert.ToInt32(m_Context.Request["price"]);
                    GetMaxBaoJia(userid,price);
                    break;
                case "Keepline":
                    Keepline(userid);
                    break;
                default:
                    break;
            }
            return _IAsyncResult;
        }
        #endregion

        #region 保持联接
        private void Keepline(string userId)
        {
            if (!dict.ContainsKey(userId))
                dict.Add(userId, _IAsyncResult);
            else //登录时虽然保存了当前用户的连接,但是登录完后异步向客户端推送了数据,此时这个客户端连接已经失效,那么在connect时相当于才是此客户端与服务器端真正的连接,需要重新更新ServerPushResult的值
                dict[userId] = _IAsyncResult;
        }
        #endregion

        #region 

        /// <summary>
        /// 获取最大报价
        /// </summary>
        /// <param name="userid"></param>
        /// <param name="price"></param>
        private void GetMaxBaoJia(string userId,int price)
        {
            if (price>tempMaxBaoJia)
            {
                tempMaxBaoJia = price;
            }
            _IAsyncResult.Result = Json(tempMaxBaoJia);
            foreach (var item in dict.Keys)
            {
                dict[item].Result = Json(tempMaxBaoJia);
                dict[item].Send();
            }
          
            //_IAsyncResult.Send();
        }
        #endregion

        /// <summary>
        /// 将对象转换成json字符串
        /// </summary>
        /// <param name="obj">对象</param>
        /// <param name="dateFormat">对象中日期要转换的格式</param>
        /// <returns></returns>
        public static String Json(object obj, String dateFormat = "yyyy-MM-dd")
        {
            IsoDateTimeConverter timeConverter = new IsoDateTimeConverter();
            timeConverter.DateTimeFormat = dateFormat;
            var jSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Converters = { timeConverter } };
            var strjson = JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.Indented, jSetting);

            strjson = Regex.Replace(strjson, @"\\/Date\((\d+)\)\\/", match =>
            {
                DateTime dt = new DateTime(1970, 1, 1);
                dt = dt.AddMilliseconds(long.Parse(match.Groups[1].Value));
                dt = dt.ToLocalTime();
                return dt.ToString(dateFormat);
            });
            return strjson;
        }
    }

 public class ServerPushResult : IAsyncResult
    {
        #region 全局变量
        HttpContext m_Context;
        AsyncCallback m_Callback;
        object m_ExtraData;
        bool m_IsCompleted = false;
        public string Result { get; set; }
        #endregion

        #region 构造函数
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="context"></param>
        /// <param name="cb"></param>
        /// <param name="extraData"></param>
        public ServerPushResult(HttpContext context, AsyncCallback cb, object extraData)
        {
            m_Context = context;
            m_Callback = cb;
            m_ExtraData = extraData;
        }
        #endregion

        #region 向客户端发送消息
        /// <summary>
        /// 向客户端响应消息
        /// </summary>
        /// <param name="result">结果信息</param>
        public void Send()
        {
            try
            {
                m_Context.Response.Write(Result);
                if (m_Callback != null)
                {
                    m_Callback(this);
                }
            }
            catch { }
            finally
            {
                m_IsCompleted = true;
            }
        }
        #endregion

        #region IAsyncResult 成员
        //获取用户定义的对象,它限定或包含关于异步操作的信息。
        public object AsyncState
        {
            get { return null; }
        }

        //获取用于等待异步操作完成的 WaitHandle。
        public WaitHandle AsyncWaitHandle
        {
            get { return null; }
        }

        //获取异步操作是否同步完成的指示。
        public bool CompletedSynchronously
        {
            get { return false; }
        }

        //获取异步操作是否已完成的指示。
        public bool IsCompleted
        {
            get { return m_IsCompleted; }
        }
        #endregion
    }

需要引用json的dllnewtonsoft.json.dll 自己网上找 因为前台规定返回是json,所以返回时需要json一下,要不然有些数据前台转换会有问题。

其实思路很简单

就是keepline发起一个 长连接 在等待 。 多个客户端,其中一个客户端 触发一个事件,后台就推送所有 消息 返回 给在等待长连接的其他客户端。


欢迎转载,尊重劳动成果,请标明出处。


本文参考http://www.cnblogs.com/zengqinglei/archive/2013/03/31/2991189.html 

http://www.ibm.com/developerworks/cn/web/wa-lo-comet/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值