1. Hidden iframe
将iframe的src指向一个url,server收到请求后,Keep-Alive。
数据直接以script的方式下发到Browser,Browser收到数据后直接执行。
只要不超时,链接会一直保留。
优:感觉这是真正的长连接,对stream也有完整的支持。
劣:Browser状态栏会一直处于“连接中”,ESC会导致链接断开,会有跨域问题
2. Script Tag
用JS创建一个script对象,将该对象的src指向一个url,Keep-Alive。
在一定时间内(超时前),如果sever有数据下发,则用script的方式发送到Browser。
Browser收到数据后直接执行,此时需要重建script对象,建立另一个链接。
优:没有Hidden iframe的缺点,也比较轻量
劣:不是真正的长链接,每收到一个新的下发数据,都需要重新建立链接
3 AJAX
用JS创建一个XHR对象,将该对象的src指向一个url,Keep-Alive。
在一定时间内(超时前),如果sever有数据下发,则通过已建立的链接发送到Browser。
Browser收到数据后直接执行,此时需要重建XHR对象,建立另一个链接。
优:没有Hidden iframe的缺点
劣:存在跨域问题,不是真正的长链接,每收到一个新的下发数据,都需要重新建立链接
2 和 3也可以叫做Long Polling
除了这三种方法,还可以用Flash,由Flash和Server通信,页面用过JS和Flash通信。
这可以实现真正的下发,甚至不需要维护长链接。
但也可能存在被防火墙屏蔽的问题。
三种方法都用php模拟了一下:
Hidden Iframe
<html> <head> <script> function callback(data) { document.getElementById("t").value = data + "\n" + document.getElementById("t").value; } callback("abc"); </script> </head> <body> hello <textarea id="t"></textarea> <iframe src="/hiddeniframe.php" width="0" height="0"></iframe> </body> </html>
<?php ob_end_flush(); echo "<script>"; echo "domain=serverpush"; echo "</script>"; for( ; ; ) { $t = time(); echo "<script>"; echo "parent.callback($t);"; echo "</script>"; flush(); sleep(1); } ?>
Script Tag
<html> <head> <script> function callback(data) { document.getElementById("t").value = data + "\n" + document.getElementById("t").value; } function connect() { var _script = document.createElement("script"); _script.setAttribute("type", "text/javascript"); _script.setAttribute("src", "script.php"); document.getElementsByTagName("head")[0].appendChild(_script); } connect(); </script> </head> <body> <textarea id="t"></textarea> </body> </html>
<?php sleep(10); $r = time(); echo "callback($r);"; echo "setTimeout(connect, 1000)"; ?>
AJAX
<html> <head> <script> function callback(data) { document.getElementById("t").value = data + "\n" + document.getElementById("t").value; } function connect() { var ajax = new XMLHttpRequest; ajax.open("POST", "ajax.php"); ajax.onreadystatechange = function() { if (ajax.readyState == 4) { if (ajax.status == 200) { callback(ajax.responseText); setTimeout(connect, 1000); } } } ajax.send(); } connect(); </script> </head> <body> <textarea id="t"></textarea> </body> </html>
<?php sleep(10); echo time(); ?>
最近评论