六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 23|回复: 0

WebIM

[复制链接]

升级  8.4%

168

主题

168

主题

168

主题

进士

Rank: 4

积分
542
 楼主| 发表于 2013-1-29 10:36:49 | 显示全部楼层 |阅读模式
WebIM开发技术细节
最近两年WebIM特别的流行,像淘宝的阿里旺旺网页版,腾讯的WEBQQ,Google的gtalk,百度hi等等都陆续推出了自己的网页版的聊天软件。实现网页的即时聊天,有一个关键的问题就是怎么样让服务器不停的往客户度发送数据,现在解决的方案一般是用:iframe 隐藏帧,flash的xmlsocket,或者使用ajax在请求未结束的时候马上发起请求。我个人觉得还是iframe的实现方式比较好,目前腾讯等都是用的iframe的方式,具体原因不解释。但是对于iframe如何传送数据是一个难点。突破这个难点一切就简单了。

  我自己参考了一些博客资料以及国外的完整后自己测试终于把这个问题给解决了,要让服务端一直发送数据首先要利用chunked传输response。

  下面列出我的实现代码:

  

XML/HTML代码1.<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
2.<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
3.<html>  
4.  <head>      
5.    <title>Iframe数据</title>  
6.    <meta http-equiv="pragma" content="no-cache">  
7.    <meta http-equiv="cache-control" content="no-cache">  
8.    <meta http-equiv="expires" content="0">      
9.    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>   
10.  </head>  
11.  <body>  
12.    数据列表:<br/>  
13.    <div id="datalist" style="width:400px;height:300px;border:1px solid #EF0;overflow: auto;">  
14.      
15.    </div>  
16.    <script type="text/javascript">  
17.        function getData(d){   
18.            $("#datalist").append(d);   
19.        }   
20.        function rpc_iframe() {   
21.            var transferDoc = new ActiveXObject("htmlfile");   
22.            transferDoc.open();   
23.            transferDoc.write("<html>")   
24.            transferDoc.write("<div><iframe src=\"IFrameStream.do\"></iframe></div>");   
25.            transferDoc.close("</html>");   
26.            transferDoc.parentWindow.getData = getData;   
27.            setInterval(function () { }, 10000);  //不加这句会使连接断开   
28.        }   
29.        rpc_iframe();   
30.    </script>  
31.      
32.  </body>  
33.</html>  
  接下来是我们后台的代码:



Java代码1.package org.javafans.chat;   
2.  
3.import java.io.IOException;   
4.import java.io.PrintWriter;   
5.import java.text.SimpleDateFormat;   
6.import java.util.Date;   
7.  
8.import javax.servlet.ServletException;   
9.import javax.servlet.annotation.WebServlet;   
10.import javax.servlet.http.HttpServlet;   
11.import javax.servlet.http.HttpServletRequest;   
12.import javax.servlet.http.HttpServletResponse;   
13.  
14.@WebServlet(urlPatterns="/IFrameStream.do")   
15.public class IFrameStreamServlet extends HttpServlet{   
16.    /**  
17.     * @Fields serialVersionUID : TODO(用一句话描述这个变量表示什么)   
18.     */  
19.    private static final long serialVersionUID = 1L;   
20.  
21.    /* (non-Javadoc)  
22.     * <p>Title: doGet</p>   
23.     * <p>Description: </p>   
24.     * @param req  
25.     * @param resp  
26.     * @throws ServletException  
27.     * @throws IOException  
28.     * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)  
29.     */  
30.    @Override  
31.    protected void doGet(HttpServletRequest req, HttpServletResponse resp)   
32.        throws ServletException, IOException {   
33.    // TODO Auto-generated method stub   
34.    this.doPost(req, resp);   
35.    }   
36.  
37.    /* (non-Javadoc)  
38.     * <p>Title: doPost</p>   
39.     * <p>Description: </p>   
40.     * @param req  
41.     * @param resp  
42.     * @throws ServletException  
43.     * @throws IOException  
44.     * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)  
45.     */  
46.    @Override  
47.    protected void doPost(HttpServletRequest req, HttpServletResponse resp)   
48.        throws ServletException, IOException {   
49.    // TODO Auto-generated method stub   
50.      
51.    //需要实时生成消息长度,服务器一般使用chunked编码。   
52.    resp.setHeader("transfer-coding", "chunked");   
53.    resp.setContentType("text/html;charset=utf8");   
54.    PrintWriter out = resp.getWriter();   
55.      
56.    String startHTML = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n";   
57.    startHTML += "<html xmlns=\"http://www.w3.org/1999/xhtml\" >\r\n" ;   
58.    startHTML += "<head>\r\n</head>\r\n" ;   
59.    startHTML += "<body>\r\n" ;   
60.      
61.    out.write(startHTML);   
62.    out.flush();   
63.      
64.    String data = "<script type=\"text/javascript\">parent.getData(\"%s\");</script>";   
65.      
66.    out.write(String.format(data, "开始发送数据<br/>"));   
67.    out.flush();   
68.    while(true){   
69.        try {   
70.        Thread.sleep(1000);   
71.        } catch (InterruptedException e) {   
72.        e.printStackTrace();   
73.        }   
74.        out.append(String.format(data,"服务端发送的数据"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())+"<br/>"));   
75.        out.flush();   
76.    }   
77.      
78.      
79.    }   
80.  
81.      
82.      
83.}
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表