WebIM

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.}
WebIM说明 WebIM是一款基于jQuery的一款web即时通讯插件,姑且这么称呼吧。插件最大程度实现了IM的常用功能,除即时通讯的常用功能外,还加入了:消息盒子、窗口抖动、添加删除好友、最近联系人、超时登录界面、网站小秘书、聊天记录、发送频率限制、发送产品、发送名片、发送表情、产品分享、黑名单、举报、收藏、公告、智能网址过滤、消息提醒、修改资料、名片二维码、禁止粘贴、收起联系人列表、推荐好友等30余项改进。全浏览器兼容。 插件调用简单方便,只需在现有的web系统中加入几行代码,理论上可嵌入任何web系统。 2012年项目,已不再维护。 配置 $(function() { $(document).FnWebIM({ autoLogin :true, //boolean型,默认是否自动登录,true:自动登录,false:手动登录,默认为true msgRefreshTime :1000, //number型,消息刷新时间,单位为ms friendRefreshTime :10000, //number型,好友刷新时间,单位为ms showSecretary :true, //boolean型,默认是否显示小秘书,true:显示,false:不显示,默认为true noticeContent :"唐僧师徒历经千辛万苦,终于见到了佛祖……", //string型,公告内容 为空时不显示公告 sendPicture :true, //boolean型,是否允许发送图片,true:允许,false:不允许,默认为true msgMaxSize :300, //number型,单条消息最大允许字符 msgSound :false, //boolean型,是否开启声音提醒,true:开启,false:关闭,默认为true defaultWindow :"" //string型,登录后打开新聊天窗口,此处接收的参数为联系人的uid,否则会出错 }); }); 详细说明文档 http://www.zi-han.net/case/im/help.html 示例 http://www.zi-han.net/developer/721.html 注意 请在服务器(如localhost)环境下打开
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值