基于iframe的HTTP长连接实现
关于什么是http长连接我不废吐沫了,有专业的解释(http://www.ibm.com/developerworks/cn/web/wa-lo-comet/)你可以去看看
我们介绍一下在struts下的实现
首先写一个test.jsp(写一些片段)
<html:form action="/myAction" target="myiframe"> <%-- 这里写你的页面代码 --%> <center><input type="button" value="测试提交" onClick="javascript:test();"></center> </html:form> <iframe name="myiframe" id="myiframe" style="display: none" mce_style="display: none"></iframe> <mce:script language="JavaScript"><!-- function orderGen(){ document.MyForm.action.value = 'test'; document.MyForm.submit(); } function msg(m){ alert(m); } // --></mce:script> 特别注意‘<html:form action="/myAction" target="myiframe">’中的target属性的值一定要等于form结尾那个iframe的名称(即name属性),这是该实现方式的原理所在,就是说这个MyForm提交服务器后由服务器响应回来的数据填充到这个iframe里面,而这个iframe是不可见的(display: none)。从而实现了提交后页面没有刷新的感觉。
接下来是服务器端的实现
public class MyAction extends DispatchAction{ public ActionForward test(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws Exception { String result = "hello I'm server";//要打印到前台的字符 sendMsg(result,response,"msg");//msg是test.jsp中的那个js方法的名称 return null;//必须返回null } //以下方法的意思是将msg打到前台页面调用前台的“function msg(m)”方法进行显示 protected void sendMsg(String msg, HttpServletResponse response, String javascriptMethod) { try { response.setContentType("text/html;charset=GBK"); response.getWriter().write( "<mce:script type="text/javascript"><!-- parent." + javascriptMethod + "(\"" + msg + "\"); // --></mce:script>"); response.flushBuffer(); } catch (Exception e) { e.printStackTrace(); } } } sendMsg这个java生成了一段js代码将服务端的数据展示在了页面,页面会打出一个alert,如果你明白了这个原理那么你可以改写sendMsg和function msg(m),你可以将数据填到一个div中,这个效果就好像ajax一样页面连闪都不闪一下。
接下来实现长连接
public class MyAction extends DispatchAction{ public ActionForward test(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws Exception { int i = 0; boolean boo = true; String result = null; while(boo){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } result = "hello I'm server"+i;//要打印到前台的字符 sendMsg(result,response,"msg");//msg是test.jsp中的那个js方法的名称 i++; if(i==100){ boo = false; } } return null; } //以下方法的意思是将msg打到前台页面调用前台的“function msg(m)”方法进行显示 protected void sendMsg(String msg, HttpServletResponse response, String javascriptMethod) { try { response.setContentType("text/html;charset=GBK"); response.getWriter().write( "<mce:script type="text/javascript"><!-- parent." + javascriptMethod + "(\"" + msg + "\"); // --></mce:script>"); response.flushBuffer(); } catch (Exception e) { e.printStackTrace(); } } } 不停的做循环操作以求达到长连接,前台会不停的打alert出来,这样做实现了服务器端向客户端推数据,同时服务器端的状态可以实时反映到前台,如果在你的项目中客户点击按钮后服务器将执行大量的长时间的操作的时候而客户又要实时监控操作的情况的时候不妨使用这种方式提升用户体验。随便说一句IE支持这种玩法firefox等浏览器也支持