我们的配置
这个servlet除了完成我们comted的初始化,还是会处理处理长轮询请求
<!-- CometD Servlet --> <servlet> <servlet-name>cometd</servlet-name> <servlet-class>org.cometd.annotation.server.AnnotationCometDServlet</servlet-class> <!--liqiang todo 600000--> <init-param> <param-name>maxProcessing</param-name> <param-value>600000</param-value> </init-param> <init-param> <param-name>timeout</param-name> <param-value>20000</param-value> </init-param> <init-param> <param-name>interval</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>maxInterval</param-name> <param-value>10000</param-value> </init-param> <init-param> <param-name>handshakeReconnect</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>maxLazyTimeout</param-name> <param-value>5000</param-value> </init-param> <init-param> <param-name>long-polling.multiSessionInterval</param-name> <param-value>2000</param-value> </init-param> <init-param> <param-name>services</param-name> <param-value>org.cometd.examples.ChatService</param-value> </init-param> <init-param> <param-name>ws.cometdURLMapping</param-name> <param-value>/cometd/*</param-value> </init-param> <!--容器启动时调用init方法初始化 而不是第一次调用时--> <load-on-startup>1</load-on-startup> <async-supported>true</async-supported> </servlet>
继承自CometDServlet
public class AnnotationCometDServlet extends CometDServlet
org.cometd.server.CometDServlet#service
@Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if ("OPTIONS".equals(request.getMethod())) { serviceOptions(request, response); return; } //<2>根据请求方式获取对应的transport 这里优先获取的是AsyncJSONTransport AbstractHttpTransport transport = _bayeux.findHttpTransport(request); if (transport == null) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Unknown Bayeux Transport"); } else { //<4>调用transport的handle 其实跟websoket很相似 websoket是websoket消息触发 http相关则是http请求触发 transport.handle(request, response); } }
org.cometd.server.BayeuxServerImpl#findHttpTransport
protected AbstractHttpTransport findHttpTransport(HttpServletRequest request) { //遍历已激活的transport for (String transportName : _allowedTransports) { ServerTransport serverTransport = getTransport(transportName); //是否是http类型的transport if (serverTransport instanceof AbstractHttpTransport) { AbstractHttpTransport transport = (AbstractHttpTransport)serverTransport; //<3>调用accept 默认有三种可选项 AsyncJSONTransport、JSONPTransport、JSONTransport if (transport.accept(request)) { return transport; } } } return null; }
org.cometd.server.http.AsyncJSONTransport#accept
@Override public boolean accept(HttpServletRequest request) { return "POST".equalsIgnoreCase(request.getMethod()); }
org.cometd.server.http.JSONPTransport#accept
@Override public boolean accept(HttpServletRequest request) { //是否是返回jspon的格式 String callbackValue = request.getParameter(getCallbackParameter()); return "GET".equals(request.getMethod()) && isCallbackValueValid(callbackValue); }
org.cometd.server.http.JSONTransport#accept
@Override public boolean accept(HttpServletRequest request) { return "POST".equals(request.getMethod()); }
后面就不读了,知道大概就行,跟websoket差不多 只是少了主动推的步骤
1.http请求 /meta/handshake 建立连接
2.http请求 /meta/subscribe 订阅渠道
3.http请求 /meta/unsubscribe 取消订阅渠道
4.http请求 /meta/disconnect 取消订阅渠道
5.http请求 /meta/connect 轮询发送心跳消息表示自己活跃,同时拉取自己session队列里面的消息
6.http请求 针对渠道发送消息,放入订阅渠道的所有sesion队列中,但是没有主动推的动作 等meta/connection来主动拉