websocket-cometd源码阅读-transport

说明

transport就是我们的处理器器,比如websoket通信,http长轮询,支持jsonp方式的长轮询

如我们的初始化配置的代码

  @Bean(initMethod = "start", destroyMethod = "stop")
    public BayeuxServer bayeuxServer() {
        BayeuxServerImpl bean = new BayeuxServerImpl();
        bean.setTransports(new WebSocketTransport(bean), new JSONTransport(bean), new JSONPTransport(bean));
        servletContext.setAttribute(BayeuxServer.ATTRIBUTE, bean);
        bean.setOption(ServletContext.class.getName(), servletContext);
        bean.setOption("ws.cometdURLMapping", "/cometd/*");
        return bean;
    }

类图

接口

Transport定义

定义一些获取transport名字 以及配置的的接口

public interface Transport {
    /**
     * @return The well known name of this transport, used in transport negotiations
     * @see Bayeux#getAllowedTransports()
     * 获得协议名称,用于请求的时候根据参数名称找到对应的处理器
     */
    String getName();

    /**
     * @param name the configuration option name
     * @return the configuration option with the given {@code qualifiedName}
     * @see #getOptionNames()
     * 获取配置相关参数
     */
    Object getOption(String name);

    /**
     * @return the set of configuration options
     * @see #getOption(String)
     * 获取配置相关参数的names
     */
    Set<String> getOptionNames();

    /**
     * Specifies an option prefix made of string segments separated by the "."
     * character, used to override more generic configuration entries.
     *
     * @return the option prefix for this transport.
     */
    String getOptionPrefix();
}

ServerTransport

服务性质的transport,比如会定义一些获取超时配置

public interface ServerTransport extends Transport {
    /**
     * @return the timeout (in milliseconds) of this transport
     * 传输超时时间
     */
    public long getTimeout();

    /**
     * @return the interval of time (in milliseconds) of this transport
     * 传输间隔,比如轮训/meta/connect
     */
    public long getInterval();

    /**
     * @return the maximum interval of time (in milliseconds) before the server consider the client lost
     * 最大间隔时间,超过这个时间服务端认为断开连接  比如多久没调用/meta/connect
     */
    public long getMaxInterval();

    /**
     * @return the maximum time (in milliseconds) before dispatching lazy messages
     * 调度延迟消息之前的最长时间(毫秒)
     */
    public long getMaxLazyTimeout();

    /**
     * @return whether the messages are delivered to clients exclusively via the "/meta/connect" channel
     * 消息是否仅通过“/meta/connect”通道传递给客户端  
     */
    public boolean isMetaConnectDeliveryOnly();
}

AbstractTransport

仅仅定义了封装transport名字以及参数,以及获得相关option参数方法的实现

public class AbstractTransport implements Transport {
    private final String _name;
    private final Map<String, Object> _options;
    private String[] _prefix = new String[0];
    private String _optionPrefix = "";

    protected AbstractTransport(String name, Map<String, Object> options) {
        _name = name;
        _options = options == null ? new HashMap<>(1) : options;
    }

    @Override
    public String getName() {
        return _name;
    }

    /**
     * Returns an option value for the given option name, searching the option name tree.
     * The option map is searched for the option name with the most specific prefix.
     * If this transport was initialized with a call to:
     * <pre>
     *   setOptionPrefix("long-polling.jsonp");
     * </pre>
     * then a call to getOption("foobar") will look for the
     * most specific value with names:
     * <pre>
     *   long-polling.json.foobar
     *   long-polling.foobar
     *   foobar
     * </pre>
     *
     * @param name the option name to return the value for.
     */
    @Override
    public Object getOption(String name) {
        Object value = _options.get(name);
        String prefix = null;
        for (String segment : _prefix) {
            prefix = prefix == null ? segment : (prefix + "." + segment);
            String key = prefix + "." + name;
            if (_options.containsKey(key)) {
                value = _options.get(key);
            }
        }
        return value;
    }

    /**
     * Sets the option value with the given name.
     * The option name is inspected to see whether it starts with the {@link #getOptionPrefix() option prefix};
     * if it does not, the option prefix is prepended to the given name.
     *
     * @param name  the option name to set the value for.
     * @param value the value of the option.
     */
    public void setOption(String name, Object value) {
        String prefix = getOptionPrefix();
        if (prefix != null && prefix.length() > 0 && !name.startsWith(prefix)) {
            name = prefix + "." + name;
        }
        _options.put(name, value);
    }

    @Override
    public String getOptionPrefix() {
        return _optionPrefix;
    }

    /**
     * Set the option name prefix segment.
     * <p> Normally this is called by the super class constructors to establish
     * a naming hierarchy for options and iteracts with the {@link #setOption(String, Object)}
     * method to create a naming hierarchy for options.
     * For example the following sequence of calls:<pre>
     *   setOption("foo","x");
     *   setOption("bar","y");
     *   setOptionPrefix("long-polling");
     *   setOption("foo","z");
     *   setOption("whiz","p");
     *   setOptionPrefix("long-polling.jsonp");
     *   setOption("bang","q");
     *   setOption("bar","r");
     * </pre>
     * will establish the following option names and values:<pre>
     *   foo: x
     *   bar: y
     *   long-polling.foo: z
     *   long-polling.whiz: p
     *   long-polling.jsonp.bang: q
     *   long-polling.jsonp.bar: r
     * </pre>
     * The various {@link #getOption(String)} methods will search this
     * name tree for the most specific match.
     *
     * @param prefix the prefix name
     * @throws IllegalArgumentException if the new prefix is not prefixed by the old prefix.
     */
    public void setOptionPrefix(String prefix) {
        if (!prefix.startsWith(_optionPrefix)) {
            throw new IllegalArgumentException(_optionPrefix + " not prefix of " + prefix);
        }
        _optionPrefix = prefix;
        _prefix = prefix.split("\\.");
    }

    @Override
    public Set<String> getOptionNames() {
        Set<String> names = new HashSet<>();
        for (String name : _options.keySet()) {
            int lastDot = name.lastIndexOf('.');
            if (lastDot >= 0) {
                name = name.substring(lastDot + 1);
            }
            names.add(name);
        }
        return names;
    }

    /**
     * Get option or default value.
     *
     * @param option   The option name.
     * @param dftValue The default value.
     * @return option or default value
     * @see #getOption(String)
     */
    public String getOption(String option, String dftValue) {
        Object value = getOption(option);
        return (value == null) ? dftValue : value.toString();
    }

    /**
     * Get option or default value.
     *
     * @param option   The option name.
     * @param dftValue The default value.
     * @return option or default value
     * @see #getOption(String)
     */
    public long getOption(String option, long dftValue) {
        Object value = getOption(option);
        if (value == null) {
            return dftValue;
        }
        if (value instanceof Number) {
            return ((Number)value).longValue();
        }
        return Long.parseLong(value.toString());
    }

    /**
     * Get option or default value.
     *
     * @param option   The option name.
     * @param dftValue The default value.
     * @return option or default value
     * @see #getOption(String)
     */
    public int getOption(String option, int dftValue) {
        Object value = getOption(option);
        if (value == null) {
            return dftValue;
        }
        if (value instanceof Number) {
            return ((Number)value).intValue();
        }
        return Integer.parseInt(value.toString());
    }

    /**
     * Get option or default value.
     *
     * @param option   The option name.
     * @param dftValue The default value.
     * @return option or default value
     * @see #getOption(String)
     */
    public boolean getOption(String option, boolean dftValue) {
        Object value = getOption(option);
        if (value == null) {
            return dftValue;
        }
        if (value instanceof Boolean) {
            return (Boolean)value;
        }
        return Boolean.parseBoolean(value.toString());
    }
}

 

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