asp.net-mvc – 在同一个流连接上返回多个结果以实现HTML5 Serve
我试图在我的MVC 4 Web上设置一个轻量级的
HTML5 Server-Sent Event实现,而不使用其中一个库来实现套接字和类似物.
我正在尝试的轻量级方法是: 客户端: 服务器端: public class HTML5testAsyncController : AsyncController { private static int curIdx = 0; private static BlockingCollection<string> _data = new BlockingCollection<string>(); static HTML5testAsyncController() { addItems(10); } //adds some test messages static void addItems(int howMany) { _data.Add("started"); for (int i = 0; i < howMany; i++) { _data.Add("HTML5 item" + (curIdx++).ToString()); } _data.Add("ended"); } // here comes the async action,'Simple' public void SimpleAsync() { AsyncManager.OutstandingOperations.Increment(); Task.Factory.StartNew(() => { var result = string.Empty; var sb = new StringBuilder(); string serializedObject = null; //wait up to 40 secs that a message arrives if (_data.TryTake(out result,TimeSpan.FromMilliseconds(40000))) { JavaScriptSerializer ser = new JavaScriptSerializer(); serializedObject = ser.Serialize(new { item = result,message = "MSG content" }); sb.AppendFormat("data: {0}nn",serializedObject); } AsyncManager.Parameters["serializedObject"] = serializedObject; AsyncManager.OutstandingOperations.Decrement(); }); } // callback which returns the results on the stream public ActionResult SimpleCompleted(string serializedObject) { ServerSentEventResult sar = new ServerSentEventResult(); sar.Content = () => { return serializedObject; }; return sar; } //pushes the data on the stream in a format conforming HTML5 SSE public class ServerSentEventResult : ActionResult { public ServerSentEventResult() { } public delegate string GetContent(); public GetContent Content { get; set; } public int Version { get; set; } public override void ExecuteResult(ControllerContext context) { if (context == null) { throw new ArgumentNullException("context"); } if (this.Content != null) { HttpResponseBase response = context.HttpContext.Response; // this is the content type required by chrome 6 for server sent events response.ContentType = "text/event-stream"; response.BufferOutput = false; // this is important because chrome fails with a "failed to load resource" error if the server attempts to put the char set after the content type response.Charset = null; string[] newStrings = context.HttpContext.Request.Headers.GetValues("Last-Event-ID"); if (newStrings == null || newStrings[0] != this.Version.ToString()) { string value = this.Content(); response.Write(string.Format("data:{0}nn",value)); //response.Write(string.Format("id:{0}n",this.Version)); } else { response.Write(""); } } } } } 问题出在服务器端,因为预期结果与实际发生的结果之间仍然存在很大差距. 预期结果: > EventSource打开与服务器的流连接, >消息1在T 0ms接收,在T x被推送到客户端 实际行为: > EventSource打开与服务器的流连接, >消息1在T 0ms接收,在T x 3200ms推送到客户端 这是不行的,因为它失败了使用SSE的目的,因为客户端再次开始重新连接,因为正常轮询和消息传递被延迟. 现在,问题是: 解决方法
您希望使用
Response.Flush发送数据,而不是依赖于SimpleComplete来发送数据.通过执行AsyncManager.OutstandingOperations.Decrement(),您告诉AsyncController您已完成处理请求并且您已准备好发送响应并关闭连接.相反,您应该避免调用OutStandingOperations.Decrement()直到连接丢失等.每当您想要将消息推送到客户端时,您直接从某个后台线程调用
Response.Write和Response.Flush.此外,AsyncControllers具有默认超时,之后它们会自动关闭连接.为了解决这个问题,您需要使用
NoAsyncTimeoutAttribute进行相关操作.
作为旁注,AsyncController的接口实际上不允许实现SSE流的干净方式;鉴于我使用的是Asp.NET MVC 4,我个人会实现HttpTaskAsyncHandler. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-mvc-4 – MVC4 RC脚本捆绑很慢
- asp.net – 如何在警告框中显示验证控件的错误消息?
- asp.net-mvc – 获取控制器mvc 4中的复选框值
- asp.net-mvc-3 – 自定义RazorViewEngine会出现页面错误
- asp.net-mvc-3 – 在具有默认值的模型上注释属性
- ASP.NET分析器错误无法加载代码
- asp.net – 在转发器中只选择一个radiobutton
- asp.net-core – 在开发中的ASP.NET核心项目上启用/禁用SSL
- asp.net – 在用户表或单独的配置文件表中存储用户配置文件
- 谈谈在.NET Core中使用Redis和Memcached的序列化问题
- 快速开发之代码生成器(asp.net mvc4 + easyui +
- 在ASP.NET MVC 5中创建对象时何时在C#中使用NEW关
- asp.net signalR 专题—— 第三篇 如何从外部线程
- asp.net-mvc – 使用ASP.NET MVC和Razor的Knocko
- 覆盖ASP.NET AJAX Control Toolkit的TabContaine
- adfs2.0 – 启用了非声明的ASP.NET应用程序和ADF
- asp.net-mvc – 如何在ASP.NET MVC 4中定义catch
- asp.net – ExecuteReader需要时间,而不是SQL服务
- asp.net-mvc – ASP.NET MVC不调用global.asax’
- asp.net-mvc – 在Mono 2.4上使用Microsoft Data