测试环境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技术的底层实现,通常涉及服务器端编程语言如Java、Python、Node.js等的源代码。开发者可以通过阅读源码来了解如何在服务器端处理长时间的连接,以及如何在数据准备好时高效...
【Comet4j】是Comet技术的一个Java实现框架,旨在简化Java开发者在应用中集成Comet技术的难度。Comet4j提供了异步处理、长轮询、HTTP流等多种策略,以适应不同的实时推送需求。通过使用Comet4j,开发人员可以轻松地...
Comet4j是这个框架的名称,它是一个基于Java技术构建的长连接通信框架,适用于需要双向通信、实时数据交换的Web应用,如聊天系统、股票交易、在线游戏等场景。 描述中提到,Comet4j框架包含了Java类库和JavaScript...
Comet4j是一种基于Java的服务器推送技术,它允许服务器主动向客户端发送数据,而无需客户端不断轮询请求。在Web应用中,这种技术能够显著提高实时性,尤其是在实时聊天、股票更新、在线游戏等场景中表现优异。该...
1. **SiteInfoServler.txt**:可能是一个服务器端处理Comet请求的示例代码,比如用Java实现的一个简单服务,演示了如何创建并维护长连接,以及如何向客户端推送数据。 2. **script.txt**:这可能是一个客户端的...
Java Comet + UDP 实现是一个在Web开发中处理实时通信的技术组合。Comet是一种服务器推送技术,主要用于构建响应式、实时的Web应用,而UDP(User Datagram Protocol)是一种无连接的传输层协议,常用于需要快速传输...
Spring整合DWR(Direct Web Remoting)以...通过DWR的Comet技术,服务器可以主动推送数据,解决了传统的HTTP短链接无法实现实时通信的问题。在实际开发中,结合Spring的优秀特性,可以构建出高效、稳定的多人聊天系统。
然而,由于没有明确的规范,长连接的实现和行为可能会有所不同。 HTTP/1.1则将长连接作为默认行为,除非在请求或响应中明确指定`Connection: close`来要求断开连接。这意味着在HTTP/1.1中,所有连接都是持久的,...
通过 BlazeDS,你可以方便地调用 Java 对象的方法,并且它还提供了远程调用(Remoting)功能以及Web消息传递(Web Messaging)功能,支持Comet样式的消息推送,使得服务器能够主动向客户端发送数据。 在Windows环境...
DWR(Direct Web Remoting)是一种Java库,用于在Web应用程序中实现Ajax功能,它允许JavaScript与服务器端的Java代码进行交互,实现页面的实时更新而无需刷新整个页面。DWR通过建立持久的HTTP连接(长连接)来提高...
【标题】"原创nio socket mina+javascript+flash实现commet长连接网页聊天室"揭示了一个基于Java NIO(Non-blocking I/O)的Socket通信框架Mina与JavaScript、Flash技术结合,实现COMET(Comet是使服务器向浏览器推...
在Java中,可以使用Servlet或者WebSocket等技术来实现这样的长连接。对于Pushlet来说,它需要能够识别用户身份,以便将消息推送给特定用户。这可能通过在连接建立时传递用户ID,或者使用cookie、session等机制来实现...
标题中的“Flex与Java Server Push数据”涉及到的技术是基于Adobe Flex客户端和Java服务器端的数据实时推送技术。...通过阅读博文链接(https://dojava.iteye.com/blog/1711575)可以获取更具体的实现细节和示例代码。
Comet是一种模拟服务器推送的技术,通过长时间保持HTTP连接(长轮询或HTTP流)来实现实时通信。在Servlet中实现Comet,服务器可以利用HTTP响应的延迟关闭特性,保持连接打开状态,当有新消息时立即发送到客户端。 ...
- **长轮询**:为了实现更实时的聊天体验,Web QQ可能采用了长轮询技术,即浏览器发送请求后,服务器保持连接直到有新消息,再将消息返回给客户端。 - **Comet技术**:一种模拟服务器推的技术,让服务器主动推送...
1. **Comet技术**:Comet是一种利用HTTP长连接实现服务器向客户端推送数据的技术。它通过长时间保持HTTP连接不关闭,使得服务器可以在合适的时候将数据写入到已打开的连接中。Comet技术包括两种主要实现方式:...
在传统的Web应用中,用户与服务器之间的交互通常是通过点击按钮或链接,然后浏览器发送请求到服务器,服务器处理后返回响应,浏览器再加载新的页面。而在反向Ajax(也称为Comet技术)中,服务器可以主动推送数据到...