首页 > 代码库 > web 伪双工(comet)全双工(websocket)学习记录,不要让你的 view承受太多
web 伪双工(comet)全双工(websocket)学习记录,不要让你的 view承受太多
写在前头:所有例子后台处理都是C#代码
comet:不赘述。
http://www.ibm.com/developerworks/cn/web/wa-lo-comet/
http://zh.wikipedia.org/wiki/Comet_(web%E6%8A%80%E6%9C%AF)
下面我们就先说说这两种模式:
长轮询模式:顾名思义,还是轮询模式,只不过是做了一些变异。(按照现在的流行应该是 “轮询plus” 之类)
首先看一下长轮询的交互图("引 IBM developerworks")
通过图片可以知道,流程就是 "ajax请求--》等待--》收到结果--》请求" 这样一个轮询过程
示例代码(js主要部分)
1 function webApply() { 2 $.ajax({ 3 url: ‘你的目标url‘, 4 type: ‘post‘,//get... 5 dataType:‘json‘,//或者其他什么 6 success: function (data) { 7 //处理逻辑 8 9 //继续请求10 webApply();11 },12 error: function (data, status) {13 //错误处理14 }15 })16 }
实例代码(这个地方我就给一个连接吧)
http://msdn.microsoft.com/zh-cn/library/ms227433(v=VS.90).aspx
注:其实不一定要异步,同步也可以,只是在服务器的消耗上有一点点区别。
简单评论一下:这样做的优点就是减少了轮询请求次数。节约了一定的资源(网络,服务器),但是缺点就是还是一个轮询法,没有实现长连接,也就是无法记录每一次请求的状态。每一次请求都是一次新的访问,一些实例对象无法共享,只能借助session对象。
再看一下第二种模式
iframe+服务:这种模式其实也不能算是长连接,是利用了iframe的异步请求效果。
这个就直接上代码
示例代码(html主要部分)
<iframe src="你的服务代码" id="importDate" name="importDate" style="display: none"></iframe>
就这样简单语句
服务器端代码
1 //Handler请求入口 2 public void ProcessRequest(HttpContext context) 3 { 4 context.Response.ContentType = "text/html;charset=utf-8"; 5 //开始执行操作 6 ExcelImport.Instance.Action(context); 7 } 8 9 internal class ExcelImport10 {11 private readonly static ExcelImport excelimport = new ExcelImport();12 internal static ExcelImport Instance13 {14 get { return excelimport; }15 }16 string o = string.Empty;17 //读取excel文件框架18 internal bool ReadExcelFreamwork(HttpContext context)19 {20 Thread.Sleep(3000);21 o = "正在读取框架";22 ThreadPool.QueueUserWorkItem(new WaitCallback(xx => {23 context.Response.Write("<script language=‘javascript‘ type=‘text/javascript‘>parent.dis(‘" + o + "‘);</script>");24 context.Response.Flush();25 })); 26 return true;27 }28 //验证excel框架29 internal bool VaildateExcelFreamwork(HttpContext context)30 {31 Thread.Sleep(3000);32 o = "正在验证框架";33 ThreadPool.QueueUserWorkItem(new WaitCallback(xx =>34 {35 context.Response.Write("<script language=‘javascript‘ type=‘text/javascript‘>parent.dis(‘" + o + "‘);</script>");36 context.Response.Flush();37 })); 38 return true;39 }40 //读取数据41 internal bool ReadData(HttpContext context)42 {43 Thread.Sleep(3000);44 o = "正在读取数据";45 ThreadPool.QueueUserWorkItem(new WaitCallback(xx =>46 {47 context.Response.Write("<script language=‘javascript‘ type=‘text/javascript‘>parent.dis(‘" + o + "‘);</script>");48 context.Response.Flush();49 })); 50 return true;51 }52 //验证数据53 internal bool ValidateData(HttpContext context)54 {55 Thread.Sleep(3000);56 o = "正在验证数据";57 ThreadPool.QueueUserWorkItem(new WaitCallback(xx =>58 {59 context.Response.Write("<script language=‘javascript‘ type=‘text/javascript‘>parent.dis(‘" + o + "‘);</script>");60 context.Response.Flush();61 })); 62 return true;63 }64 //导入数据65 internal bool ImportData(HttpContext context)66 {67 Thread.Sleep(3000);68 o = "正在导入数据";69 ThreadPool.QueueUserWorkItem(new WaitCallback(xx =>70 {71 context.Response.Write("<script language=‘javascript‘ type=‘text/javascript‘>parent.dis(‘" + o + "‘);</script>");72 context.Response.Flush();73 })); 74 return true;75 }76 77 internal bool Finsh(HttpContext context)78 {79 Thread.Sleep(3000);80 o = "finsh";81 ThreadPool.QueueUserWorkItem(new WaitCallback(xx =>82 {83 context.Response.Write("<script language=‘javascript‘ type=‘text/javascript‘>parent.dis(‘" + o + "‘);</script>");84 context.Response.Flush();85 })); 86 return true;87 }88 89 internal void Action(object o)90 {91 HttpContext context = (HttpContext)o;92 ReadExcelFreamwork(context);93 VaildateExcelFreamwork(context);94 ReadData(context);95 ValidateData(context);96 ImportData(context);97 Finsh(context);98 }99 }
注:代码中有很多多余,可以忽略
简单评论一下:优点就是一次请求,反馈结果,
缺点就是:1、这是一个同步的,所以占用服务器资源(异步此方法就无效了)
2、居所在IE6、7、8上会有鼠标等待状态,视觉效果差
针对缺点2有一群牛A想出了这样一个办法(本人未实验,因为我用的是IE11)
引
使用 iframe 请求一个长连接有一个很明显的不足之处:IE、Morzilla Firefox 下端的进度栏都会显示加载没有完成,而且 IE 上方的图标会不停的转动,表示加载正在进行;刷新当前页面反应也是会很慢。
解决IE的进度栏显示加载没有完成,可以使用一个称为“htmlfile”的 ActiveX,是Google 的天才们使用的方法,该控件也被用到gmail+gtalk 产品中。
修改Default.aspx的页面代码:
<div id="con" style=" width:400; height:200px; border:1px solid #FF0"> </div> <script type="text/javascript"> function getData(d) { $("#con").append(d); } function rpc_iframe() { var transferDoc = new ActiveXObject("htmlfile"); transferDoc.open(); transferDoc.write("<html>") transferDoc.write("<div><iframe src=http://www.mamicode.com/"Flush.aspx\"></iframe></div>"); transferDoc.close("</html>"); transferDoc.parentWindow.getData = getData; setInterval(function () { }, 10000); //不加这句会使连接断开 } rpc_iframe(); </script>
好了,下面我就在学一学websocket吧,HTML5的新特性,多么令人激动的事情,可是,可但是有些浏览器就是成长的这么慢
吼吼,马上下班了 先mark个地址,所有在学吧
https://developer.mozilla.org/zh-CN/docs/WebSockets
<script type="text/javascript"> var websocket; var connected = false; function doConnect(wsURI) { if (connected) { debug_output_f("<span style=‘color:red;‘>You‘re already connected!</span>"); } else { websocket = new WebSocket(wsURI); websocket.onopen = function(evt) { onOpen(evt) }; websocket.onclose = function(evt) { onClose(evt) }; websocket.onmessage = function(evt) { onMessage(evt) }; websocket.onerror = function(evt) { one rror(evt) }; debug_output_f("CONNECTION REQUESTED ...."); } } function onOpen (evt) { connected = true; debug_output_f("CONNECTED"); } function onClose (evt) { connected = false; websocket.close(); debug_output_f("DISCONNECTED"); } function onMessage (evt) { debug_output_f("<span style=‘color: blue;‘>RESP: " + evt.data + "</span>"); } function one rror (evt) { debug_output_f("<span style=‘color:red;‘>ERROR:</span> " + evt.data); } function doSend (msg) { if (connected) { websocket.send(msg); debug_output_f("SENT: " + msg); /* { // binary size = msg.length; var ba = new Uint8Array(size); for (var i=0; i<size; i++) { ba[i] = msg.charCodeAt(i); } m = ba.buffer; websocket.send(m); debug_output_f("SENT: binary message"); } */ } else { debug_output_f("<span style=‘color: red;‘>NOT CONNECTED: No message sent.</span>"); } } function doClose () { if (connected) { debug_output_f("CLOSING ...."); websocket.close(); connected=false; } else { debug_output_f("<span style=‘color: red;‘>NOT CONNECTED</span>"); } } </script>
web 伪双工(comet)全双工(websocket)学习记录,不要让你的 view承受太多