自动采集推送(一个前端师弟问我怎样做实时聊天窗口,我惊呆了)

优采云 发布时间: 2021-11-02 11:01

  自动采集推送(一个前端师弟问我怎样做实时聊天窗口,我惊呆了)

  【背景】

  今天有个前端小辈问我如何制作实时聊天窗口。我毫不犹豫的说:前台定期访问服务器!小弟默默百度,最后告诉我有一种技术,就是post-server推送信息给客户端。这项技术的名称是彗星。我愣住了,因为我从来没有听说过,所以我赶紧上网搜集资料。花了一个晚上,写了一个简单的例子,主动向客户端发送信息。说是主动,但实际上,客户必须先给它“第一次”,也就是只要先问你,你以后就熟悉了,如果你想拿主动问吧,请教吧!

  Comet技术的介绍及其实现原理请参考网站的介绍。

  简单来说就是客户端向服务器发送请求。服务器会阻塞请求,直到有数据传输或超时才返回。之后,客户端 JavaScript 响应处理函数会在处理完服务器返回的信息后再次发出请求,重新建立连接。当客户端处理接收到的数据并重新建立连接时,新的数据可能会到达服务器端;这些信息会被服务器端保存,直到客户端重新建立连接,客户端会一次性从当前服务器端获取所有信息。

  【工作环境】

  1、myeclipse2013

  2、tomcat 6.0

  3、jdk 7

  4、火狐浏览器

  阐明:

  测试成功的浏览器有:(1)火狐浏览器(2)IE10、IE9、IE8(3)360极速浏览器极速模式)

  测试失败的浏览器有:(1)IE10兼容模式,IE7

  【准备好工作了】

  1、下载comet4j.js:

  2、下载comet4j-tomcat6.jar:

  3、 进入到tomcat目录——conf——server.xml,并把

  变成:

    

  阐明:

  其实js文件和jar官网是对的,不过是谷歌,这里是天朝,所以我把两个包的地址贴在我的文件夹里。

  Comet4j-tomcat6.jar 还有一个版本,comet4j-tomcat7.jar,选择合适的版本下载。6以下的Tomcat肯定不行。

  Comet4j.js 的官方文档:

  Comet4j-tomcat6.jar的官方文档:

  【新建项目流程】

  (1) 新增服务端类 TestComet,实现 ServletContextListener 接口

  (2)*敏*感*词*应该在web.xml中配置:

  

org.comet4j.core.CometAppListener

HelloWorld

com.zjm.www.test.TestComet

CometServlet

CometServlet

org.comet4j.core.CometServlet

CometServlet

/conn

  注意:有两个地方需要配置

  一个是comet4j-tomcat6.jar下的servlet:et4j.core.CometServlet,客户端入口

  另一个是comet4j-tomcat6.jar下的*敏*感*词*器:et4j.core.CometAppListener,它*敏*感*词*我们自己的类。

  【具体代码(说明写在注释中)】

  1、web.xml

  

  

   1

2

7

8 org.comet4j.core.CometAppListener

9

10

11 HelloWorld

12 com.zjm.www.test.TestComet

13

14

15 CometServlet

16 CometServlet

17 org.comet4j.core.CometServlet

18

19

20 CometServlet

21 /conn

22

23

24

25

26 index.jsp

27

28

  查看代码

  2、java 类 TestComet

  附有很多注释。如果你想仔细研究,建议阅读上面给出的API文档链接。

  

  

   1 package com.zjm.www.test;

2

3 import javax.servlet.ServletContextEvent;

4 import javax.servlet.ServletContextListener;

5

6 import org.comet4j.core.CometContext;

7 import org.comet4j.core.CometEngine;

8

9 /**

10 * 描述:服务端主动推送消息到客户端 简单例子

11 * @author zjm

12 * @time 2014/8/7

13 */

14 public class TestComet implements ServletContextListener {

15

16 // 频道1

17 private static final String CHANNEL1 = "result1";

18 // 频道2

19 private static final String CHANNEL2 = "result2";

20

21 // 通过频道1推送给前台的变量1

22 private static int number1 = 0 ;

23 // 通过频道2推送给前台的变量2

24 private static int number2 = 100 ;

25

26 /**

27 * 初始化上下文

28 */

29 public void contextInitialized(ServletContextEvent arg0) {

30

31 // CometContext : Comet4J上下文,负责初始化配置、引擎对象、连接器对象、消息缓存等。

32 CometContext cc = CometContext.getInstance();

33 // 注册频道,即标识哪些字段可用当成频道,用来作为向前台传送数据的“通道”

34 cc.registChannel(CHANNEL1);

35 cc.registChannel(CHANNEL2);

36

37 Thread myThread = new Thread(new SendToClientThread(), "SendToClientThread");

38 // 下面的内部类的方法是个死循环,设置helloAppModule线程为“守护线程”,则当jvm只剩“守护线程”时(主线程结束),该线程也会结束。

39 myThread.setDaemon(true);

40 // 开始线程

41 myThread.start();

42 }

43

44 /**

45 * 内部类线程类

46 */

47 class SendToClientThread implements Runnable {

48 public void run() {

49 while (true) {

50 try {

51 Thread.sleep(1000);

52 } catch (Exception ex) {

53 ex.printStackTrace();

54 }

55 // CometEngine : 引擎,负责管理和维持连接,并能够必要的发送服务

56 CometEngine engine = CometContext.getInstance().getEngine();

57 // 参数的意思:通过什么频道(CHANNEL1)发送什么数据(number1++),前台可用可用频道的值(result1)来获取某频道发送的数据

58 engine.sendToAll(CHANNEL1, number1++);

59 engine.sendToAll(CHANNEL2, number2++);

60 }

61 }

62 }

63

64 public void contextDestroyed(ServletContextEvent arg0) {

65 }

66 }

  查看代码

  3、客户端代码

  

  

   1 DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

2

3

4

5 Comet4J Hello World

6

7

8 function init(){

9

10 var number1 = document.getElementById('number1');

11 var number2 = document.getElementById('number2');

12 // 建立连接,conn 即web.xml中 CometServlet的

13 JS.Engine.start('conn');

14 // *敏*感*词*后台某个频道

15 JS.Engine.on(

16 {

17 // 对应服务端 “频道1” 的值 result1

18 result1 : function(num1){

19 number1.innerHTML = num1;

20 },

21 // 对应服务端 “频道2” 的值 result2

22 result2 : function(num2){

23 number2.innerHTML = num2;

24 },

25 }

26 );

27 }

28

29

30

31 数字1:...

32 数字2:...

33

34

  查看代码

  4、网页展示

  数字1:2221

数字2:2321

  可以看出,这两个数字每秒都在不断增加。数字2比数字1多100,因为在服务器上,number2的初始值为100,number1的初始值为0。

  在浏览器上按F12,选择网络,如下图,可以看到这个连接一直没有断开。

  

  写的不好或者写的不好,欢迎大家提出~

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线