cometd源碼閱讀-長輪詢處理消息過程(八)

我們的配置

這個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 

<1>

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);
        }
    }

<2>

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;
    }

<3>

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());
    }

<4>

後面就不讀了,知道大概就行,跟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來主動拉

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章