一般情况下,采用长连接,能持续的在客户端显示信息。
比如
- <%@ page language="java" c pageEncoding="utf-8"%>
- <%
- out.flush();
- int number = 0;
- while (true) {
- out.println(new java.util.Date()+"
- ");
- out.flush();
- Thread.sleep(100);
- System.out.print(".");
- if (number++ > 100) {
- break;
- }
- }
- %>
这个代码会在客户端连续的显示时间。请注意,浏览器的正在下载是一直在运行中的。这个会让客户感到疑惑,难道还有东西在运行吗?
下面的这个方法,可以解决这个问题
我们先看服务器端代码。
使用了prototype.js
- <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <title>Comet php backend</title>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- </head>
- <body>
- <script type="text/JavaScript">
- // KHTML browser don't share JavaScripts between iframes
- var is_khtml = navigator.appName.match("Konqueror") || navigator.appVersion.match("KHTML");
- if (is_khtml)
- {
- var prototypejs = document.createElement('script');
- prototypejs.setAttribute('type','text/JavaScript');
- prototypejs.setAttribute('src','../js/prototype.js');
- var head = document.getElementsByTagName('head');
- head[0].appendChild(prototypejs);
- }
- // load the comet object
- var comet = window.parent.comet;
- </script>
- <%
- out.flush();
- int number = 0;
- while (true) {
- // 这里生成了调用js的代码
- out.println("<script type='text/javascript'>comet.printServerTime('" + new java.util.Date() + "');</script>");
- out.flush();
- Thread.sleep(100);
- // 控制台显示,程序正在运行,正式运行可去掉
- System.out.print(".");
- // 防止程序一直运行,给调试带来麻烦,正式运行可去掉
- if (number++ > 100) {
- break;
- }
- }
- %>
关键在客户端代码
- <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <title>Comet demo</title>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <script type="text/javascript" src="../js/prototype.js"></script>
- </head>
- <body>
- <div id="content">The server time will be shown here</div>
- <script type="text/javascript">
- var url= 'testLinkData2.jsp';
- var comet = {
- connection : false,
- iframediv : false,
- initialize: function() {
- if (navigator.appVersion.indexOf("MSIE") != –1) {
- // For IE browsers
- comet.connection = new ActiveXObject("htmlfile");
- comet.connection.open();
- comet.connection.write("<html>");
- comet.connection.write("<script>document.domain = '"+document.domain+"'");
- comet.connection.write("</html>");
- comet.connection.close();
- comet.iframediv = comet.connection.createElement("div");
- comet.connection.appendChild(comet.iframediv);
- comet.connection.parentWindow.comet = comet;
- comet.iframediv.innerHTML = "<iframe id='comet_iframe' src='./"+url+"'></iframe>";
- } else if (navigator.appVersion.indexOf("KHTML") != –1) {
- // for KHTML browsers
- comet.connection = document.createElement('iframe');
- comet.connection.setAttribute('id', 'comet_iframe');
- comet.connection.setAttribute('src', './'+url);
- with (comet.connection.style) {
- position = "absolute";
- left = top = "-100px";
- height = width = "1px";
- visibility = "hidden";
- }
- document.body.appendChild(comet.connection);
- } else {
- // For other browser (Firefox…)
- comet.connection = document.createElement('iframe');
- comet.connection.setAttribute('id', 'comet_iframe');
- with (comet.connection.style) {
- left = top = "-100px";
- height = width = "1px";
- visibility = "hidden";
- display = 'none';
- }
- comet.iframediv = document.createElement('iframe');
- comet.iframediv.setAttribute('src', './'+url);
- comet.connection.appendChild(comet.iframediv);
- document.body.appendChild(comet.connection);
- }
- },
- // this function will be called from backend.php
- printServerTime: function (time) {
- $('content').innerHTML = time;
- },
- onUnload: function() {
- if (comet.connection) {
- comet.connection = false; // release the iframe to prevent problems with IE when reloading the page
- }
- }
- }
- Event.observe(window, "load", comet.initialize);
- Event.observe(window, "unload", comet.onUnload);
- </script>
- </body>
- </html>
请注意其中的
comet.connection = new ActiveXObject("htmlfile");
部分,就是这段代码生成了一个可以在IE浏览器下面,不再显示正在下载状态。据说这个是google的聪明人发现并应用于google的gtalk和gmail
最后,我们来看使用Ajax的查询方式,
服务器端在没有数据的情况下会阻塞,直到有数据。
服务器端
- <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
- <%
- out.flush();
- int number = 0;
- while (true) {
- // 这里可以插入检测的代码,我后面直接休眠100毫秒代替了
- out.println("{'timestamp':'"+System.currentTimeMillis()+"','msg':'"+ new java.util.Date() + "'}");
- out.flush();
- Thread.sleep(100);
- System.out.print(".");
- if (number++ > 1) {
- break;
- }
- break;
- }
- %>
看关键的客户端
- <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <title>Comet demo</title>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <script type="text/javascript" src="../js/prototype.js"></script>
- </head>
- <body>
- <div id="content">内容</div>
- <script type="text/javascript">
- var Comet = Class.create();
- Comet.prototype = {
- timestamp: 0,
- url: './testLinkData3.jsp',
- noerror: true,
- initialize: function() { },
- connect: function()
- {
- this.ajax = new Ajax.Request(this.url, {
- method: 'get',
- parameters: { 'timestamp' : this.timestamp },
- onSuccess: function(transport) {
- // handle the server response
- var response = transport.responseText.evalJSON();
- this.comet.timestamp = response['timestamp'];
- this.comet.handleResponse(response);
- this.comet.noerror = true;
- },
- onComplete: function(transport) {
- // send a new ajax request when this request is finished
- if (!this.comet.noerror)
- // if a connection problem occurs, try to reconnect each 5 seconds
- setTimeout(function(){ comet.connect() }, 5000);
- else
- this.comet.connect();
- this.comet.noerror = false;
- }
- });
- this.ajax.comet = this;
- },
- disconnect: function()
- {
- },
- handleResponse: function(response)
- {
- $('content').innerHTML += '<div>' + response['msg'] + '</div>';
- },
- doRequest: function(request)
- {
- new Ajax.Request(this.url, {
- method: 'get',
- parameters: { 'msg' : request }
- });
- }
- }
- var comet = new Comet();
- comet.connect();
- </script>
- </body>
- </html>
几个相关的文献