`

java 实现长链接Comet

    博客分类:
  • web
 
阅读更多

测试环境Tomcat7

Servlet3以后才支持异步Servlet, Tomcat7中才支持. 其他jsp服务器没有测试.

1. Servlet

 

 import java.io.IOException;
 import java.util.Enumeration;
 import java.util.UUID;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import net.sf.json.JSONObject;
 

 public class CometServlet extends HttpServlet {
 
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
         doPost(req, resp);
     }
 
     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
         System.out.println("CometServlet" + req);
         Object UserId = req.getSession().getAttribute("UserId");
         if (UserId == null) {
             UserId = UUID.randomUUID().toString();
             req.getSession().setAttribute("UserId", UserId);
         }
         System.out.println("Userid=" + UserId);
         if (!req.isAsyncStarted()) {
             req.startAsync();
         }
         resp.addHeader("Connection", "keep-alive");
         resp.addHeader("Content-Type", "text/html; charset=utf-8");
         Enumeration<String> names = req.getParameterNames();
 
         JSONObject json = new JSONObject();
         String key;
         while (names.hasMoreElements()) {
             key = names.nextElement();
             json.put(key, req.getParameter(key));
         }
         AsynResult asynResult = new AsynResult(req.getAsyncContext(), json,
                 UserId.toString());
         AsynMsg.getInstance().AddClient(asynResult);
     }
 }

 

2. 同步消息缓存

 

   import javax.servlet.AsyncContext;
import javax.servlet.ServletResponse;

import net.sf.json.JSONObject;

public class AsynResult {
    private AsyncContext context;
    private JSONObject json;
    private String userId;

    public AsyncContext getContext() {
        return context;
    }

    public JSONObject getJson() {
        return json;
    }

    public String getUserId() {
        return userId;
    }

    public AsynResult(AsyncContext context, JSONObject json, String userId) {
        this.context = context;
        this.json = json;
        this.userId = userId;
    }

    public void send(JSONObject json) {
        try {
            ServletResponse rep = context.getResponse();
            rep.setContentType("application/json;charset=UTF-8");
            rep.setCharacterEncoding("UTF-8");
            rep.getWriter().write(json.toString());
        } catch (Exception e) {
        }
    }
}

 

3. 消息处理

 

import java.util.HashMap;
import java.util.Map;

import net.sf.json.JSONObject;

 
public class AsynMsg {
    // List<AsynResult> clients = new ArrayList<AsynResult>();
    private Map<String, AsynResult> clients = new HashMap<String, AsynResult>();
    // region 实现该类的单例
    private static final AsynMsg _Instance = new AsynMsg();
    private static final String KEY = "msg";

    private AsynMsg() {
    }

    public static AsynMsg getInstance() {
        return _Instance;
    }

    public void AddClient(AsynResult result) {
        String type = result.getJson().optString("type", "data");
        String to = result.getJson().optString("to", null);
        String user = result.getUserId();
        String from = user;

        if (type.equals("wait")) {
            if("lott".equals(result.getJson().optString("msgType",""))){
                user = "lott";
            }
            clients.put(user, result);
            try {
                synchronized (clients) {
                    clients.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            if("".equals(type)){
                to = "lott";
            }
            JSONObject json = new JSONObject();
            json.put(KEY, user + ":" + result.getJson().getString("asynMsg"));
            // 将当前请求的内容输出到客户端
            result.send(json);

            // 否则将遍历所有已缓存的client,并将当前内容输出到客户端
            sendMsg(user + ":" + result.getJson().getString("asynMsg"), from,
                    to,type);
        }

    }

    public void sendMsg(String content) {
        sendMsg(content, "系统", null, "data");
    }

    // / <summary>
    // / 遍歷所有客戶端, 將消息傳送給客戶端
    // / </summary>
    // / <param name="orderType"></param>
    public void sendMsg(String content, String from, String to, String type) {
        synchronized (clients) {
            clients.notifyAll();
        }
        JSONObject json = new JSONObject();
        json.put(KEY, content);
        json.put("from", from);
        json.put("to", to);
        json.put("type", type);
        System.out.println(json);
        if (to == null || to.toUpperCase().equals("ALL")) {
            for (AsynResult value : clients.values()) {
                value.send(json);
                value.getContext().complete();
            }
            // 清空所有缓存
            clients.clear();
        } else {
            AsynResult value = clients.get(to);
            value.send(json);
            System.out.println(value.getContext().getRequest().isAsyncStarted());
            if(value.getContext().getRequest().isAsyncStarted()){
            value.getContext().complete();
            }
        }
    }
}

 

4. 通过jsp建立长链接

http://localhost:8080/Comet/CometServlet?content=&type=wait

 

5. 通过jsp响应长链接

http://localhost:8080/Comet/json/home!SendMsg.do

 

6. 通过java程式模拟http建立长链接

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.ResourceBundle;

import net.sf.json.JSONObject;

public class HttpCometUtils {
    // private static String host = "http://localhost:8080/Comet/";
    private static String action = "json/home!SendMsg.do?msgType=ALL";
    protected static ResourceBundle projectBundle = ResourceBundle
            .getBundle("DataBaseServer");
    public static Thread CometThread = null;
    private static String host = projectBundle.getString("web_server");
    public static boolean isLogin = false;
    static {
        if (!host.endsWith("/")) {
            host += "/";
        }
    }

    public HttpCometUtils() {
        // host = "http://localhost:8080/Comet/";
        if (!host.endsWith("/")) {
            host += "/";
        }
    }

    /**
     * @param urlString
     * @param method
     * @param type
     * @param msg
     * @throws IOException
     */
    public static void connectServer() {
        new Thread() {
            @Override
            public void run() {
                int errorCount = 0;
                while (isLogin) {
                    if (errorCount >= 10) {
                        try {
                            Thread.sleep(15000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                            break;
                        }
                    }
                    URL url = null;
                    HttpURLConnection urlConnection = null;
                    try {
                        String serverURL = host
                                + "CometServlet?content=&type=wait&msgType=lott";
                        System.out.println(serverURL);
                        url = new URL(serverURL);

                        urlConnection = (HttpURLConnection) url
                                .openConnection();

                        urlConnection.setRequestMethod("GET");
                        urlConnection.setDoOutput(true);
                        urlConnection.setDoInput(true);
                        urlConnection.setUseCaches(false);
                        InputStream is = urlConnection.getInputStream();
                        byte[] b = new byte[is.available()];
                        is.read(b);
                        String jsmsg = new String(b, "utf-8");
                        System.out.println(jsmsg);
                        if(jsmsg.equals("")){
                            jsmsg = "{}";
                        }
                        JSONObject json = JSONObject.fromObject(jsmsg);
                        Object obj = null;
                        if (json.containsKey("type")) {
                            obj = json.get("type");
                            if (obj != null && "lott".equals(obj)) {
                                json = (JSONObject) json.get("msg");
                                if (json.containsKey("chatMsg")) {                                    
                                    System.out.println(json.get("chatMsg"));
                                }
                            }

                        }

                        errorCount = 0;
                    } catch (MalformedURLException e) {
                        errorCount++;
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IOException e) {
                        errorCount++;
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (Exception e) {
                        errorCount++;
                        e.printStackTrace();
                    } finally {

                        if (urlConnection != null) {
                            urlConnection.disconnect();
                        }
                    }

                }
            }
        }.start();
    }

    public static void main(String[] args) {
        int x = new Random(System.currentTimeMillis()).nextInt(100);
        HttpCometUtils.isLogin = true;
        HttpCometUtils.connectServer();
    }
}

 

7. 通过java程式模拟http响应长链接

 

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Random;
import java.util.ResourceBundle;

public class HttpUtils {
    // private static String host = "http://localhost:8080/Comet/";
    private static String action = "json/home!SendMsg.do?msgType=ALL";
    protected static ResourceBundle projectBundle = ResourceBundle
            .getBundle("DataBaseServer");
    private static String host = "http://localhost:8080/Comet";//projectBundle.getString("web_server");
    static {
        if (!host.endsWith("/")) {
            host += "/";
        }
    }

    public HttpUtils() {
        if (!host.endsWith("/")) {
            host += "/";
        }
    }

    /**
     * @param urlString
     * @param method
     * @param type
     * @param msg
     * @throws IOException
     */
    public static void send(final String type, final String asynMsg) {
        new Thread() {
            @Override
            public void run() {


                URL url = null;
                HttpURLConnection urlConnection = null;
                try {
                    StringBuffer param = new StringBuffer();
                    param.append("&type=").append(type);
                    param.append("&asynMsg=").append(URLEncoder.encode(asynMsg, "UTF-8"));
                    String urlString = param.toString();
                    
                    String serverURL = host + action + urlString;
                    System.out.println(serverURL);
                    url = new URL(serverURL);
                    
                    urlConnection = (HttpURLConnection) url.openConnection();

                    urlConnection.setRequestMethod("GET");
                    // urlConnection.setDoOutput(true);
                    // urlConnection.setDoInput(true);
                    urlConnection.setUseCaches(false);

                    System.out.println(urlConnection.getResponseMessage());
                } catch (MalformedURLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (urlConnection != null) {
                        urlConnection.disconnect();
                    }
                }

            }

        }.start();
    }

    public static void main(String[] args) {
        int x = new Random(System.currentTimeMillis()).nextInt(100);
        HttpUtils.send("chat", "恭喜您中奖了.");
    }
}

 

分享到:
评论

相关推荐

    Comet link

    【标签】:“源码”提示我们可以关注Comet技术的底层实现,通常涉及服务器端编程语言如Java、Python、Node.js等的源代码。开发者可以通过阅读源码来了解如何在服务器端处理长时间的连接,以及如何在数据准备好时高效...

    comet4j+tomcat6+tomcat7并附完整版Demo

    【Comet4j】是Comet技术的一个Java实现框架,旨在简化Java开发者在应用中集成Comet技术的难度。Comet4j提供了异步处理、长轮询、HTTP流等多种策略,以适应不同的实时推送需求。通过使用Comet4j,开发人员可以轻松地...

    消息推送comet4jjar包

    Comet4j是这个框架的名称,它是一个基于Java技术构建的长连接通信框架,适用于需要双向通信、实时数据交换的Web应用,如聊天系统、股票交易、在线游戏等场景。 描述中提到,Comet4j框架包含了Java类库和JavaScript...

    comet4j整套开发包最新版

    Comet4j是一种基于Java的服务器推送技术,它允许服务器主动向客户端发送数据,而无需客户端不断轮询请求。在Web应用中,这种技术能够显著提高实时性,尤其是在实时聊天、股票更新、在线游戏等场景中表现优异。该...

    comet初级入门指南

    1. **SiteInfoServler.txt**:可能是一个服务器端处理Comet请求的示例代码,比如用Java实现的一个简单服务,演示了如何创建并维护长连接,以及如何向客户端推送数据。 2. **script.txt**:这可能是一个客户端的...

    java commet+udp实现例子

    Java Comet + UDP 实现是一个在Web开发中处理实时通信的技术组合。Comet是一种服务器推送技术,主要用于构建响应式、实时的Web应用,而UDP(User Datagram Protocol)是一种无连接的传输层协议,常用于需要快速传输...

    Spring整合DWR comet 实现无刷新 多人聊天室

    Spring整合DWR(Direct Web Remoting)以...通过DWR的Comet技术,服务器可以主动推送数据,解决了传统的HTTP短链接无法实现实时通信的问题。在实际开发中,结合Spring的优秀特性,可以构建出高效、稳定的多人聊天系统。

    http长连接

    然而,由于没有明确的规范,长连接的实现和行为可能会有所不同。 HTTP/1.1则将长连接作为默认行为,除非在请求或响应中明确指定`Connection: close`来要求断开连接。这意味着在HTTP/1.1中,所有连接都是持久的,...

    使用BlazeDS实现Flex与Java通信

    通过 BlazeDS,你可以方便地调用 Java 对象的方法,并且它还提供了远程调用(Remoting)功能以及Web消息传递(Web Messaging)功能,支持Comet样式的消息推送,使得服务器能够主动向客户端发送数据。 在Windows环境...

    dwr长连接demo

    DWR(Direct Web Remoting)是一种Java库,用于在Web应用程序中实现Ajax功能,它允许JavaScript与服务器端的Java代码进行交互,实现页面的实时更新而无需刷新整个页面。DWR通过建立持久的HTTP连接(长连接)来提高...

    原创nio socket mina+javascript+flash实现commet长连接网页聊天室

    【标题】"原创nio socket mina+javascript+flash实现commet长连接网页聊天室"揭示了一个基于Java NIO(Non-blocking I/O)的Socket通信框架Mina与JavaScript、Flash技术结合,实现COMET(Comet是使服务器向浏览器推...

    pushlet_向在线的特定用户发送消息的单线程应用

    在Java中,可以使用Servlet或者WebSocket等技术来实现这样的长连接。对于Pushlet来说,它需要能够识别用户身份,以便将消息推送给特定用户。这可能通过在连接建立时传递用户ID,或者使用cookie、session等机制来实现...

    Flex与java Server Push数据

    标题中的“Flex与Java Server Push数据”涉及到的技术是基于Adobe Flex客户端和Java服务器端的数据实时推送技术。...通过阅读博文链接(https://dojava.iteye.com/blog/1711575)可以获取更具体的实现细节和示例代码。

    web聊天 serverpush servlet实现

    Comet是一种模拟服务器推送的技术,通过长时间保持HTTP连接(长轮询或HTTP流)来实现实时通信。在Servlet中实现Comet,服务器可以利用HTTP响应的延迟关闭特性,保持连接打开状态,当有新消息时立即发送到客户端。 ...

    Web QQ(ajax 实现的一个QQ程序)

    - **长轮询**:为了实现更实时的聊天体验,Web QQ可能采用了长轮询技术,即浏览器发送请求后,服务器保持连接直到有新消息,再将消息返回给客户端。 - **Comet技术**:一种模拟服务器推的技术,让服务器主动推送...

    服务器推送技术

    1. **Comet技术**:Comet是一种利用HTTP长连接实现服务器向客户端推送数据的技术。它通过长时间保持HTTP连接不关闭,使得服务器可以在合适的时候将数据写入到已打开的连接中。Comet技术包括两种主要实现方式:...

    反向Ajax的聊天室

    在传统的Web应用中,用户与服务器之间的交互通常是通过点击按钮或链接,然后浏览器发送请求到服务器,服务器处理后返回响应,浏览器再加载新的页面。而在反向Ajax(也称为Comet技术)中,服务器可以主动推送数据到...

Global site tag (gtag.js) - Google Analytics