java 使用 comet4j 主动向客户端推送GPS信息的简单例子

时间:2022-08-26 18:40:18

        项目开发过程中我们遇到无页面刷新请求后台服务器,经常会用到的是 ajax 技术,但是如果我们需要频繁的请求服务器该怎么办呢?

       我们首先可能想到的用 setInterval 函数 设置一个 间隔时间, 调用 ajax 方法向服务器发起请求,有没有更好一点的方式呢?有那就是采用 comet4j框架来实现,服务器主动

向客户端来推送消息。


Comet4J 框架介绍

Comet4J(Comet for Java)是一个纯粹基于AJAX(XMLHTTPRequest)的服务器推送框架,消息以JSON方式传递,具备长轮询、长连接、自动选择三种工作模式。

功能特性

  • 推送消息广播。
  • 推送定向消息。
  • 提供连接上线前、上线、下线前、下线、发送消息等多种可处理事件。
  • 消息缓存机制,确保长轮询工作模式下不丢失消息。
  • 客户端正常下线,服务端可立即感知。
  • 客户端异常停止工作,服务端可定时检查并感知。
  • 以注册通道应用的方式,让开发者对框架功能进行扩展,实现自己的应用。

框架特性

  • 独立小巧,不依赖于第三方包。
  • 与应用紧密集成,无需独立应用或服务器。
  • 与Session无关的连接机制,为开发人员提供最大程度的功能可控性。
  • 面向事件编程,客户端与服务器端均为事件驱动开发模式,提供了良好的可扩展性机制。
  • 各项性能参数均可配置。
  • 支持多种主流浏览器,并支持Air应用环境。

          

           本文通过一个小例子程序,来演示一下基于服务器推送框架 Comet4J,后台模拟实时生成 gps 坐标信息然后再推送到前端页面显示。


    工作环境

    1、myeclipse2013

    2、tomcat 7.0

    3、jdk 1.7

    4、火狐浏览器


    配置说明

    1、首先需要打开 tomcat 7 下conf 目录下的server.xml 文件,把

      <Connectorport="8080" protocol="HTTP/1.1"

                  connectionTimeout="20000"

                  redirectPort="8443" URIEncoding="UTF-8"/>

     

    修改为:

     

    <Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"

               connectionTimeout="20000"

               redirectPort="8443"URIEncoding="UTF-8"/>


    2、拷贝 comet4j 的 js 文件和 jar 包到工程中。

    java 使用 comet4j 主动向客户端推送GPS信息的简单例子


    代码说明

    第一步:配置 comet 框架,及 gps 消息分发监听器

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
        <listener>
            <listener-class>org.comet4j.core.CometAppListener</listener-class>
        </listener>
        <servlet>
            <display-name>CometServlet</display-name>
            <servlet-name>CometServlet</servlet-name>
            <servlet-class>org.comet4j.core.CometServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>CometServlet</servlet-name>
            <url-pattern>/cometConn</url-pattern>
        </servlet-mapping>

        <listener>
            <description>GPSAlarmObserver</description>
            <listener-class>org.comet4j.listener.GPSAlarmObserver</listener-class>
        </listener>
      <welcome-file-list>
         <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
    </web-app>


    第二步: 编写 gps 消息模拟器 GPSAlarmObserver.java 文件

    package org.comet4j.listener;

    import java.util.Random;
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    import org.comet4j.core.CometContext;
    import org.comet4j.core.CometEngine;


    /**
     * 作者:          Mitchell
     * 工程名:      comet
     * 包名:          org.comet4j.listener
     * 文件名:      GPSAlarmObserver.java
     * 创建日期:  Nov 12, 2015 3:53:06 PM
     */
    public class GPSAlarmObserver implements ServletContextListener {
        private static final String CHANNEL = "gpsListener";

        private java.text.DecimalFormat df = new java.text.DecimalFormat("#.####");
        
        public void contextInitialized(ServletContextEvent arg0) {
            CometContext cc = CometContext.getInstance();
            cc.registChannel(CHANNEL);// 注册应用的channel

            Thread publisher = new Thread(new GPSMessagePublisher(),
                    "Sender App Module");
            publisher.setDaemon(true);
            publisher.start();

        }

        
        /**
         * gps 信号模拟分发器,每隔一秒钟随机产生新的 坐标
         * 格式:116.3708 , 39.3963
         */
        class GPSMessagePublisher implements Runnable {
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(1000);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }

                    float coords_x = 0, coords_y = 0;
                    String coords = "";
                    Random random= new Random();
                
                    coords_x = 116+random.nextFloat();
                    coords = df.format(coords_x);
                
                    coords_y = 39+random.nextFloat();
                    coords += " , " + df.format(coords_y);
                    

                    CometEngine engine = CometContext.getInstance().getEngine();
                    engine.sendToAll(CHANNEL, coords);
                    // Runtime.getRuntime().freeMemory()/1024

                }
            }
        }

        public void contextDestroyed(ServletContextEvent arg0) {

        }
    }


    第三步: 写个页面 index.jsp测试调用一下


    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    <%
        String path = request.getContextPath();
        String basePath = request.getScheme() + "://"
                + request.getServerName() + ":" + request.getServerPort()
                + path + "/";
    %>

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    <base href="<%=basePath%>">

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Comet4J 实时接收 gps 位置消息的例子</title>
    <script type="text/javascript" src="js/comet4j.js"></script>
    <script type="text/javascript">
        function init() {
            try {
                //alert();
                var kbDom = document.getElementById('result');
                JS.Engine.on({
                    gpsListener : function(kb) {//侦听一个channel
                        //alert('kb='+kb);
                        kbDom.innerHTML = kb;
                    }
                });
                JS.Engine.start('cometConn');
                JS.Engine.on('start', function(cId, channelList, engine) {
                    alert('连接已建立,连接ID为:' + cId);
                });
            } catch (err) {
                alert(err.message);
            }
        }
    </script>
    </head>
    <body onload="init()">
        收到后台发送的 GPS 实时位置消息:
        <span id="result">...</span>
    </body>
    </html>


    演示效果如下:

    java 使用 comet4j 主动向客户端推送GPS信息的简单例子

    (注:每隔一秒钟会自动刷新坐标位置)


    源代码下载地址:  comet 模拟 gps 消息的例子