使用SignalR实现asp.net服务器端的推送(Server Push)
我们在开发Web应用时,有时候需要将Server端的的信息Push到客户端。常见的一个场景就是微博应用,需要将一个用户的收听实时消息推送到Web端,也就是用户的更新用户的Timeline。
对此通用的解决方案就是Long Polling——支持XMLHttpRequest的浏览器都可以使用,使得其适用范围广。对此需要注意的就是Server端的处理能力,最好能用类似Node.js的Non-Block式的并发。GitHub有个项目SignalR使得的在asp.net中实现Server Side的Push变得简单。为了使用SignalR,我们需要在NuGet中搜索SignalR并安装。
安装完成后我们便可以使用SignalR了,我们先看Client端的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | <! 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 runat="server"> < title >Welcome to Microblog</ title > < script src="../Scripts/jquery-1.6.4.js" type="text/javascript"></ script > < script src="../Scripts/jquery.signalR.js" type="text/javascript"></ script > < script src="../signalr/hubs"></ script > </ head > < body > < form id="form1" runat="server"> < div > < div > < span >MicroBlog ID:</ span >< input type="text" id="uid" name="uid" value=" " /> < input type="button" name="refreshTimeline" id="refreshTimeline" value="Refresh Timeline" /> </ div > < ul id="messages"></ ul > </ div > </ form > < script type="text/javascript"> $(function () { // Proxy created on the fly var conn = $.connection.microBlogServer; // Declare a function so the server can invoke it conn.newMessage = function (msg) { $('#messages').append('< li >' + msg + '</ li >'); }; conn.notify = function(notice) { $('#messages').append('< li >[system notice]:\t' + notice + '</ li >'); } // Start the connection $.connection.hub.start(); //call server side refresh when all things ready $("#refreshTimeline").click(function() { conn.refreshTimeline($('#uid').val()); }); }); </ script > </ body > </ html > |
服务器端也十分简单:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | public class MicroBlogServer:Hub, IDisconnect { private static Dictionary< string , bool > cancelQueue = new Dictionary< string , bool >(); public void RefreshTimeline( string uid) { cancelQueue.Add( this .Context.ConnectionId, false ); var msgTask = new Task( new Action< object >(PushUserMessage), uid); msgTask.Start(); } private void PushUserMessage( object uid) { while ( true ) { if (cancelQueue[ this .Context.ConnectionId]) { cancelQueue.Remove( this .Context.ConnectionId); return ; } string msg = GetNewMessage(uid.ToString()); Caller.newMessage(msg); //push new message to client string notice = GetSystemNotification(); if (! string .IsNullOrEmpty(notice)) Clients.notify(notice); } } public System.Threading.Tasks.Task Disconnect() { if (cancelQueue.Keys.Contains( this .Context.ConnectionId)) { cancelQueue[ this .Context.ConnectionId] = true ; } return null ; } #region User Message Generator private string GetNewMessage( string uid) { Thread.Sleep(3000); return string .Format( "message from xxx to {0} ({1})" , uid, DateTime.Now); } private string GetSystemNotification() { if ( new Random().Next(6) >= 5) return "system will shutdown for maintenance" ; else return string .Empty; } #endregion } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库