cometd源码阅读-长轮询处理消息过程(八)

2022/9/15 14:19:30

本文主要是介绍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来主动拉

 



这篇关于cometd源码阅读-长轮询处理消息过程(八)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程