• java 实现长链接Comet


    测试环境Tomcat7

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

    1. Servlet

    View Code
     1 import java.io.IOException;
     2 import java.util.Enumeration;
     3 import java.util.UUID;
     4 
     5 import javax.servlet.ServletException;
     6 import javax.servlet.http.HttpServlet;
     7 import javax.servlet.http.HttpServletRequest;
     8 import javax.servlet.http.HttpServletResponse;
     9 
    10 import net.sf.json.JSONObject;
    11 
    12 13 14 
    15 public class CometServlet extends HttpServlet {
    16 
    17     @Override
    18     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
    19             throws ServletException, IOException {
    20         doPost(req, resp);
    21     }
    22 
    23     @Override
    24     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
    25             throws ServletException, IOException {
    26         System.out.println("CometServlet" + req);
    27         Object UserId = req.getSession().getAttribute("UserId");
    28         if (UserId == null) {
    29             UserId = UUID.randomUUID().toString();
    30             req.getSession().setAttribute("UserId", UserId);
    31         }
    32         System.out.println("Userid=" + UserId);
    33         if (!req.isAsyncStarted()) {
    34             req.startAsync();
    35         }
    36         resp.addHeader("Connection", "keep-alive");
    37         resp.addHeader("Content-Type", "text/html; charset=utf-8");
    38         Enumeration<String> names = req.getParameterNames();
    39 
    40         JSONObject json = new JSONObject();
    41         String key;
    42         while (names.hasMoreElements()) {
    43             key = names.nextElement();
    44             json.put(key, req.getParameter(key));
    45         }
    46         AsynResult asynResult = new AsynResult(req.getAsyncContext(), json,
    47                 UserId.toString());
    48         AsynMsg.getInstance().AddClient(asynResult);
    49     }
    50 }

    2. 同步消息缓存

    View Code
     1 import javax.servlet.AsyncContext;
     2 import javax.servlet.ServletResponse;
     3 
     4 import net.sf.json.JSONObject;
     5 
     6 public class AsynResult {
     7     private AsyncContext context;
     8     private JSONObject json;
     9     private String userId;
    10 
    11     public AsyncContext getContext() {
    12         return context;
    13     }
    14 
    15     public JSONObject getJson() {
    16         return json;
    17     }
    18 
    19     public String getUserId() {
    20         return userId;
    21     }
    22 
    23     public AsynResult(AsyncContext context, JSONObject json, String userId) {
    24         this.context = context;
    25         this.json = json;
    26         this.userId = userId;
    27     }
    28 
    29     public void send(JSONObject json) {
    30         try {
    31             ServletResponse rep = context.getResponse();
    32             rep.setContentType("application/json;charset=UTF-8");
    33             rep.setCharacterEncoding("UTF-8");
    34             rep.getWriter().write(json.toString());
    35         } catch (Exception e) {
    36         }
    37     }
    38 }

    3. 消息处理

    View Code
     1 import java.util.HashMap;
     2 import java.util.Map;
     3 
     4 import net.sf.json.JSONObject;
     5 
     6  7 
     8 public class AsynMsg {
     9     // List<AsynResult> clients = new ArrayList<AsynResult>();
    10     private Map<String, AsynResult> clients = new HashMap<String, AsynResult>();
    11     // region 实现该类的单例
    12     private static final AsynMsg _Instance = new AsynMsg();
    13     private static final String KEY = "msg";
    14 
    15     private AsynMsg() {
    16     }
    17 
    18     public static AsynMsg getInstance() {
    19         return _Instance;
    20     }
    21 
    22     public void AddClient(AsynResult result) {
    23         String type = result.getJson().optString("type", "data");
    24         String to = result.getJson().optString("to", null);
    25         String user = result.getUserId();
    26         String from = user;
    27 
    28         if (type.equals("wait")) {
    29             if("lott".equals(result.getJson().optString("msgType",""))){
    30                 user = "lott";
    31             }
    32             clients.put(user, result);
    33             try {
    34                 synchronized (clients) {
    35                     clients.wait();
    36                 }
    37             } catch (InterruptedException e) {
    38                 e.printStackTrace();
    39             }
    40         } else {
    41             if("".equals(type)){
    42                 to = "lott";
    43             }
    44             JSONObject json = new JSONObject();
    45             json.put(KEY, user + ":" + result.getJson().getString("asynMsg"));
    46             // 将当前请求的内容输出到客户端
    47             result.send(json);
    48 
    49             // 否则将遍历所有已缓存的client,并将当前内容输出到客户端
    50             sendMsg(user + ":" + result.getJson().getString("asynMsg"), from,
    51                     to,type);
    52         }
    53 
    54     }
    55 
    56     public void sendMsg(String content) {
    57         sendMsg(content, "系统", null, "data");
    58     }
    59 
    60     // / <summary>
    61     // / 遍歷所有客戶端, 將消息傳送給客戶端
    62     // / </summary>
    63     // / <param name="orderType"></param>
    64     public void sendMsg(String content, String from, String to, String type) {
    65         synchronized (clients) {
    66             clients.notifyAll();
    67         }
    68         JSONObject json = new JSONObject();
    69         json.put(KEY, content);
    70         json.put("from", from);
    71         json.put("to", to);
    72         json.put("type", type);
    73         System.out.println(json);
    74         if (to == null || to.toUpperCase().equals("ALL")) {
    75             for (AsynResult value : clients.values()) {
    76                 value.send(json);
    77                 value.getContext().complete();
    78             }
    79             // 清空所有缓存
    80             clients.clear();
    81         } else {
    82             AsynResult value = clients.get(to);
    83             value.send(json);
    84             System.out.println(value.getContext().getRequest().isAsyncStarted());
    85             if(value.getContext().getRequest().isAsyncStarted()){
    86             value.getContext().complete();
    87             }
    88         }
    89     }
    90 }

    4. 通过jsp建立长链接

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

    5. 通过jsp响应长链接

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

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

    View Code
    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响应长链接

    View Code
    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", "恭喜您中奖了.");
        }
    }
  • 相关阅读:
    转:SLAM算法解析:抓住视觉SLAM难点,了解技术发展大趋势
    在ROS系统下,获取tango的RGBD信息和Pose信息
    ubuntu更改源为aliyun的源;ROS改为新加坡源
    PCL学习(五)如何在mesh模型上sample更多点及三维物体姿态估计
    利用StringBuffer向字符串特定的重复子字符串插入数据
    poi做Excel数据驱动,支持.xls和.xlsx格式的excel文档,比起jxl强大不少
    selenium grid的使用与配置
    maven下载,安装与eclipse中maven配置
    Webdriver实现对菜单栏的灵活切换功能,附上代码,类似的菜单栏切换可以自己封装
    Webdriver控制翻页控件,并实现向前向后翻页功能,附上代码,仅供参考,其他类似日期控件的功能可以自己封装
  • 原文地址:https://www.cnblogs.com/liubin0509/p/2781093.html
Copyright © 2020-2023  润新知