java 实现长链接Comet
测试环境Tomcat7
Servlet3以后才支持异步Servlet, Tomcat7中才支持. 其他jsp服务器没有测试.
1. Servlet
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. 同步消息缓存
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. 消息处理
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建立长链接
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() {@Overridepublic 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() {@Overridepublic 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", "恭喜您中奖了.");} }
java 实现长链接Comet相关推荐
- java,url长链接生成短链接,短链接生成器,自定义字符串,对字符串md5混合KEY加密,根据短链接获得key值,不重复的随机数,不重复的随机字符串...
java,url长链接生成短链接,短链接生成器,自定义字符串,对字符串md5混合KEY加密,根据短链接获得key值,不重复的随机数,不重复的随机字符串 1 package com.zdz.test; ...
- Java建立长链接的方式_java http长链接(keep-alive)导致的问题
两种由http长链接(keep-alive)导致的问题,当然这两种问题都有多种原因导致,这里只分析针对keep-alive相关而产生的异常. 1 SocketException: Connection ...
- java keeplive,java http长链接(keep-alive)导致的问题
两种由http长链接(keep-alive)导致的问题,当然这两种问题都有多种原因导致,这里只分析针对keep-alive相关而产生的异常. 1 SocketException: Connection ...
- java 服务器长链接_Java如何实现长连接
实现原理: 长连接的维持,是要客户端程序,定时向服务端程序,发送一个维持连接包的. 如果,长时间未发送维持连接包,服务端程序将断开连接. 客户端: Client通过持有Socket的对象,可以随时(使 ...
- Java把长链接变成短链接_借助第三方,java长链接转短链接,IP域名同样支持
短信和微博中用到短链接,短链接的主要职责就是把原始链接很长的地址压缩成短链接地址,当点击这个链接后,又可以跳转到原始链接地址. package common.util; import java.uti ...
- java实现短链接得到长链接!!!
java实现短链接得到长链接!!! 重点:params.setParameter(ClientPNames.HANDLE_REDIRECTS, false);//禁止重定向,不设置(有些短链接)获取不 ...
- 扫盲!Java可变长数组,看这篇就对了!
来自:ImportNew/覃佑桦 | 责编:乐乐 链接:tutorials.jenkov.com/java-performance/resizable-array.html 有时我们希望将把数据保存在 ...
- java url 短链接_推荐几个官方腾讯短链接url接口(含PHP演示代码)
腾讯短链接url接口是腾讯官方对外发布的短链接生成接口,可以将长链接缩短生成类似于 "http://url.cn/xxxx" 格式的url,相较于新浪短链接的广泛应用场景,腾讯短链 ...
- Java实现短链接URL生成
因公司推广需要,需要一套短链接生成方案,正好前几天在MSDN看到有人发了一个.net版的短链接算法,我就把它转换成java版,拿出来共享一下 生成思路: 1.将"原始链接(长链接)+key( ...
最新文章
- Kubernetes 集群使用 Jenkins 持续发布
- php lumen auth,学习 Lumen 用户认证 (一)
- 有关git clone 下载速度变慢的解决方法
- 【Android APT】注解处理器 ( 注解标注 与 初始化方法 )
- WebSphere MQ 自动启动发送方通道
- JS难点剖析-原型原型链
- C++绝不在构造和析构过程中调用virtual函数
- 通过100个单词掌握英语语法(四十四)more
- mysql数据库工程师网易微专业_网易MySQL数据库工程师微专业学习笔记(五)
- fastapi学习(二):路径参数获取与GET、POST参数获取
- li中浮动元素span等在IE和Firefox中的高度Bug
- 概率论与数理统计——随机变量及其分布
- 北风:信息差有多重要?你是怎么被割韭菜的?
- 异形与铁血战士关系 时间线
- PHP:Fatal error: Class 'COM' not found in … 的处理办法
- 记一次golang memory leak的解决过程
- 微信步数C语言程序,获取微信步数 - osc_1v2pb1nt的个人空间 - OSCHINA - 中文开源技术交流社区...
- source insight 4.0 选择后,相同单词全部高亮
- CycleGan人脸转为漫画脸,牛掰的知识又增加了!| 附代码
- tflearn教程_利用 TFLearn 快速搭建经典深度学习模型
热门文章
- 赛门铁克:业务整合才是正道,并非一心二用
- 老李分享:Android性能优化之内存泄漏 3
- Ext.js4.x 的面板中嵌入UEditor编辑器
- 虚拟机 搭建LVS + DR + keepalived 高可用负载均衡
- Python 之glob模块
- 我们离DevOps有多远--持续集成思想的延伸
- flink sql client讀取kafka數據的timestamp(DDL方式)
- 为什么是hbase而不是mongodb
- dpkg: 錯誤: 分析檔案 '/var/lib/dpkg/updates/0001' 的第 0 行附近: 欄位名稱 `#padding' 中有換行
- theano中的Rop和Lop的详细解释