基于iframe的HTTP长连接实现

来源:互联网 发布:白泽球 淘宝 编辑:程序博客网 时间:2024/04/29 16:22

 
关于什么是http长连接我不废吐沫了,有专业的解释(http://www.ibm.com/developerworks/cn/web/wa-lo-comet/)你可以去看看
我们介绍一下在struts下的实现
首先写一个test.jsp(写一些片段)

view plaincopy to clipboardprint?
<html:form action="/myAction" target="myiframe"> 
    <%-- 这里写你的页面代码 --%>     
    <center><input type="button" value="测试提交" class="btn4" 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">
    <%-- 这里写你的页面代码 --%> 
    <center><input type="button" value="测试提交" class="btn4" 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)。从而实现了提交后页面没有刷新的感觉。
接下来是服务器端的实现

view plaincopy to clipboardprint?
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();  
        }  
    }  

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一样页面连闪都不闪一下。
接下来实现长连接
view plaincopy to clipboardprint?
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();  
        }  
    }  

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等浏览器也支持

 

注意:HTTP 1.1 规范中规定,客户端不应该与服务器端建立超过两个的 HTTP 连接, 新的连接会被阻塞。而 IE 在实现中严格遵守了这种规定。所以不能建立两个以上的长连接。本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/fhp0917/archive/2009/05/12/4171818.aspx

原创粉丝点击