java 实现长链接Comet
测试环境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", "恭喜您中奖了."); } }
相关推荐
WebVincent 2020-07-21
fengchao000 2020-07-04
baijinswpu 2020-06-28
88483063 2020-06-28
fengchao000 2020-06-16
somebodyoneday 2020-06-15
wujiajax 2020-06-14
somebodyoneday 2020-05-16
xx0cw 2020-05-16
newthon 2020-05-14
sailxu00 2020-04-27
fengchao000 2020-04-20
88483063 2020-01-29
83163452 2020-01-28
baijinswpu 2020-01-25
baijinswpu 2020-01-18