cometd через websocket: неизвестный транспорт Байё

Я пытаюсь подключиться к серверу commetd через клиент websocket. Я использовал именно тот код из официальная демонстрация cometd на github без изменений и попробуйте подключиться к http://localhost:8080/cometd/test

.. но как только мой клиент пытается выполнить http-запрос обновления веб-сокета, я получаю ответ «HTTP / 1.1 400 Неизвестный транспорт Байё». Есть идеи?

Я пробовал использовать SSL и без него, последнее явно для уменьшения потенциальных источников ошибок. В обоих случаях я получаю одну и ту же ошибку.

Вот мой pom, на случай, если я забыл некоторые важные зависимости, связанные с веб-сокетами

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                      http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>de.verlinkied</groupId>
    <artifactId>bayeux-server</artifactId>
    <version>1.0</version>


    <properties>
        <jetty.version>9.2.22.v20170606</jetty.version>
        <cometd.version>3.1.3</cometd.version>
        <slf4j.version>1.7.25</slf4j.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.eclipse.jetty.websocket</groupId>
            <artifactId>websocket-api</artifactId>
            <version>${jetty.version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>${jetty.version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlet</artifactId>
            <version>${jetty.version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-jmx</artifactId>
            <version>${jetty.version}</version>
        </dependency>


        <dependency>
            <groupId>org.eclipse.jetty.websocket</groupId>
            <artifactId>javax-websocket-server-impl</artifactId>
            <version>${jetty.version}</version>
        </dependency>

        <dependency>
            <groupId>org.cometd.java</groupId>
            <artifactId>cometd-java-server</artifactId>
            <version>${cometd.version}</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <configuration>
                    <mainClass>de.verlinked.BayeuxServerTest</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

mvn dependency: tree дает следующее

[INFO] ------------------------------------------------------------------------
[INFO] Building bayeux-server 1.0
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ bayeux-server ---
[INFO] de.verlinkied:bayeux-server:jar:1.0
[INFO] +- org.eclipse.jetty.websocket:websocket-api:jar:9.2.22.v20170606:compile
[INFO] +- org.eclipse.jetty:jetty-server:jar:9.2.22.v20170606:compile
[INFO] |  +- javax.servlet:javax.servlet-api:jar:3.1.0:compile
[INFO] |  +- org.eclipse.jetty:jetty-http:jar:9.2.22.v20170606:compile
[INFO] |  \- org.eclipse.jetty:jetty-io:jar:9.2.22.v20170606:compile
[INFO] +- org.eclipse.jetty:jetty-servlet:jar:9.2.22.v20170606:compile
[INFO] |  \- org.eclipse.jetty:jetty-security:jar:9.2.22.v20170606:compile
[INFO] +- org.eclipse.jetty:jetty-jmx:jar:9.2.22.v20170606:compile
[INFO] |  \- org.eclipse.jetty:jetty-util:jar:9.2.22.v20170606:compile
[INFO] +- org.eclipse.jetty.websocket:javax-websocket-server-impl:jar:9.2.22.v20170606:compile
[INFO] |  +- org.eclipse.jetty:jetty-annotations:jar:9.2.22.v20170606:compile
[INFO] |  |  +- org.eclipse.jetty:jetty-plus:jar:9.2.22.v20170606:compile
[INFO] |  |  |  \- org.eclipse.jetty:jetty-jndi:jar:9.2.22.v20170606:compile
[INFO] |  |  +- org.eclipse.jetty:jetty-webapp:jar:9.2.22.v20170606:compile
[INFO] |  |  |  \- org.eclipse.jetty:jetty-xml:jar:9.2.22.v20170606:compile
[INFO] |  |  +- javax.annotation:javax.annotation-api:jar:1.2:compile
[INFO] |  |  +- org.ow2.asm:asm:jar:5.0.1:compile
[INFO] |  |  \- org.ow2.asm:asm-commons:jar:5.0.1:compile
[INFO] |  |     \- org.ow2.asm:asm-tree:jar:5.0.1:compile
[INFO] |  +- org.eclipse.jetty.websocket:javax-websocket-client-impl:jar:9.2.22.v20170606:compile
[INFO] |  |  \- org.eclipse.jetty.websocket:websocket-client:jar:9.2.22.v20170606:compile
[INFO] |  +- org.eclipse.jetty.websocket:websocket-server:jar:9.2.22.v20170606:compile
[INFO] |  |  +- org.eclipse.jetty.websocket:websocket-common:jar:9.2.22.v20170606:compile
[INFO] |  |  \- org.eclipse.jetty.websocket:websocket-servlet:jar:9.2.22.v20170606:compile
[INFO] |  \- javax.websocket:javax.websocket-api:jar:1.0:compile
[INFO] +- org.cometd.java:cometd-java-server:jar:3.1.3:compile
[INFO] |  +- org.cometd.java:bayeux-api:jar:3.1.3:compile
[INFO] |  \- org.cometd.java:cometd-java-common:jar:3.1.3:compile
[INFO] |     \- org.eclipse.jetty:jetty-util-ajax:jar:9.2.22.v20170606:compile
[INFO] +- org.slf4j:slf4j-api:jar:1.7.25:compile
[INFO] \- org.slf4j:slf4j-log4j12:jar:1.7.25:compile
[INFO]    \- log4j:log4j:jar:1.2.17:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

Журнал причала показывает следующее

3411 [qtp1080615555-20] DEBUG org.eclipse.jetty.server.HttpChannel  - HttpChannelOverHttp@31f5a8ff{r=1,c=false,a=IDLE,uri=/cometd/test} messageComplete
3411 [qtp1080615555-20] DEBUG org.eclipse.jetty.server.HttpInput  - HttpInputOverHTTP@6f0992d0 EOF
3411 [qtp1080615555-20] DEBUG org.eclipse.jetty.server.HttpChannel  - HttpChannelOverHttp@31f5a8ff{r=1,c=false,a=IDLE,uri=/cometd/test} handle enter
3412 [qtp1080615555-20 - /cometd/test] DEBUG org.eclipse.jetty.server.HttpChannelState  - HttpChannelState@738a2171{s=IDLE i=true a=null} handling IDLE
3412 [qtp1080615555-20 - /cometd/test] DEBUG org.eclipse.jetty.server.HttpChannel  - HttpChannelOverHttp@31f5a8ff{r=1,c=false,a=DISPATCHED,uri=/cometd/test} action REQUEST_DISPATCH
3412 [qtp1080615555-20 - /cometd/test] DEBUG org.eclipse.jetty.server.Server  - REQUEST GET /cometd/test on HttpChannelOverHttp@31f5a8ff{r=1,c=false,a=DISPATCHED,uri=/cometd/test}
3412 [qtp1080615555-20 - /cometd/test] DEBUG org.eclipse.jetty.server.handler.ContextHandler  - scope null||/cometd/test @ o.e.j.s.ServletContextHandler@35fdf572{/,null,AVAILABLE}
3413 [qtp1080615555-20 - /cometd/test] DEBUG org.eclipse.jetty.server.handler.ContextHandler  - context=||/cometd/test @ o.e.j.s.ServletContextHandler@35fdf572{/,null,AVAILABLE}
3413 [qtp1080615555-20 - /cometd/test] DEBUG org.eclipse.jetty.servlet.ServletHandler  - servlet |/cometd|/test -> org.cometd.server.CometDServlet-629a2d4a@4553b89a==org.cometd.server.CometDServlet,1,true
3413 [qtp1080615555-20 - /cometd/test] DEBUG org.eclipse.jetty.servlet.ServletHandler  - chain=Jetty_WebSocketUpgradeFilter->org.cometd.server.CometDServlet-629a2d4a@4553b89a==org.cometd.server.CometDServlet,1,true
3414 [qtp1080615555-20 - /cometd/test] DEBUG org.eclipse.jetty.servlet.ServletHandler  - call filter Jetty_WebSocketUpgradeFilter
3416 [qtp1080615555-20 - /cometd/test] DEBUG org.eclipse.jetty.servlet.ServletHandler  - call servlet org.cometd.server.CometDServlet-629a2d4a@4553b89a==org.cometd.server.CometDServlet,1,true
3418 [qtp1080615555-20 - /cometd/test] DEBUG org.eclipse.jetty.server.HttpConnection  - org.eclipse.jetty.server.HttpConnection$SendCallback@62e6f50[PROCESSING][i=ResponseInfo{HTTP/1.1 400 Unknown Bayeux Transport,304,false},cb=org.eclipse.jetty.server.HttpChannel$CommitCallback@6892f8b1] generate: NEED_HEADER (null,[p=0,l=304,c=2048,r=304],true)@START

Где вы можете видеть, что вызывается какой-то Jetty_WebSocketUpgradeFilter, что заставляет меня думать, что зависимость от веб-сокета присутствует, но все же что-то идет не так.


person Magnus Lutz    schedule 03.01.2018    source источник
comment
На каком сервере вы развертываете свое веб-приложение? Я спрашиваю, потому что вы используете привязки WebSocket CometD для Jetty, которые требуют Jetty в качестве сервера. Укажите также точную версию сервера.   -  person sbordet    schedule 03.01.2018
comment
пример в предоставленной ссылке использует встроенный причал, версия - 9.2.23.v20171218, как указано в свойствах pom   -  person Magnus Lutz    schedule 03.01.2018


Ответы (2)


Jetty предлагает 2 разных варианта WebSocket: стандартный JSR 356 и специальный для Jetty.

Первый обозначается в артефактах Maven с помощью javax в имени артефакта, а второй обозначается причалом в имени артефакта.

Из указанного выше POM вы используете cometd-java-websocket-jetty-server, который является привязкой CometD к причалу WebSocket.

Однако вы явно указываете в качестве зависимости артефакт javax-websocket-server-impl, который является разновидностью JSR 356 javax.

Я предполагаю, что если вы сделаете зависимости согласованными, то это будет зависеть только от вкуса javax или только от вкуса jetty, который решит вашу проблему.

Если вам не нужно использовать специальные функции Jetty, я бы порекомендовал вам использовать JSR 356 javax как для привязки CometD (org.cometd.java:cometd-java-websocket-javax-server), так и для зависимости Jetty (org.eclipse.jetty.websocket:javax-websocket-server-impl).

person sbordet    schedule 03.01.2018
comment
Я пробовал использовать только javax-websocket-server-impl, также скорректировал свой вопрос, показывая mvn dependency: tree. Все еще не повезло - person Magnus Lutz; 04.01.2018
comment
Вы никогда не показывали свой встроенный код, поэтому убедитесь, что ваш код похож на тот, который представлен в этом разделе документации CometD, в частности, вызов WebSocketServerContainerInitializer для инициализации WebSocket. - person sbordet; 04.01.2018
comment
Это точный код из этого ссылка, как указано в вопросе, который также относится к предоставленному вами разделу - person Magnus Lutz; 04.01.2018
comment
Таким образом, код взят из реального теста, и поэтому он работает правильно. Чем отличается ваша конфигурация и демо CometD? - person sbordet; 04.01.2018
comment
это именно то, что я пытаюсь выяснить! Я надеялся, что зависимости каким-то образом различаются, и особенно, что что-то, связанное с веб-сокетами, отсутствует, но, похоже, нет, а? - person Magnus Lutz; 04.01.2018
comment
Если вы получаете неизвестную транспортную ошибку, это означает, что HTTP-запрос, который обновляется до WebSocket, не перехватывается WebSocketUpgradeFilter, установленным Jetty под крышками (если WebSocketServerContainerInitializer вызывается правильно). Итак, две вещи: 1) вызовите server.dumpStdErr () после того, как вы запустили сервер, он должен показать, есть ли фильтр; 2) сделайте дамп сети, чтобы убедиться, что запрос обновления WebSocket законен. - person sbordet; 04.01.2018
comment
это то, что я думал в первую очередь, но в журнале написано, что фильтр вызовов Jetty_WebSocketUpgradeFilter - person Magnus Lutz; 08.01.2018
comment
Журнал также показывает, что после WebSocketUpgradeFilter вызывается CometDServlet, что означает, что по какой-то причине обновление WebSocket было неудачным, и фильтр просто перенаправил запрос. Вам необходимо включить уровень DEBUG для WebSocketUpgradeFilter, чтобы узнать больше о том, что делает фильтр, или просто отладить его. - person sbordet; 08.01.2018
comment
У меня уже есть только один log4j rootLogger, который настроен на отладку и который, похоже, используется причалом и cometd. Я не уверен, смогу ли я получить больше выходов из этого - person Magnus Lutz; 08.01.2018

У меня была такая же проблема. Я пытался это отследить. Мне кажется, что это вызвано тем, как сервер bayeux инициализирует сопоставления транспорта веб-сокетов из свойства ws.cometdURLMapping. Либо так, либо я использую неправильное значение ws.cometdURLMapping.

Предполагая, что зависимости веб-сокетов настроены правильно, поэтому при использовании jsr 356 запросы на обновление веб-сокетов проходят через Jetty WebSocketUpgradeFilter.doFilter(). Этот метод проверяет, является ли запрос допустимым запросом на обновление веб-сокетов и что одно из его сопоставлений соответствует пути запроса веб-сокета.

Вот где у меня что-то не получается. Удачного совпадения не бывает.

Я настроил ws.cometdURLMapping на /cometd/*. Я ожидал, что это будет означать, что любой запрос веб-сокета для /cometd/<whatever/here> будет принят.

Этого не происходит, потому что AbstractWebSocketTransport.normalizeURLMapping () преобразует /cometd/* в /cometd, который AFAICS интерпретируется с помощью Код веб-сокета Jetty в виде регулярного выражения. Вот фрагмент кода кометы, о котором я говорю:

protected List<String> normalizeURLMapping(String urlMapping) {
    String[] mappings = urlMapping.split(",");
    List<String> result = new ArrayList<>(mappings.length);
    for (String mapping : mappings) {
        if (mapping.endsWith("/*")) {
            mapping = mapping.substring(0, mapping.length() - 2);
        }
        if (!mapping.startsWith("/")) {
            mapping = "/" + mapping;
        }
        result.add(mapping);
    }
    return result;
}

Регулярное выражение ^/cometd$ определенно не соответствует моему пути запроса веб-сокета, который равен /cometd/ или /cometd/something-here, поэтому фильтр обновления веб-сокета игнорируется.

Я не отслеживал, что происходит после этого, но предполагаю, что, поскольку транспорт не отмечен как доступный, сервер кометы просто отключается с помощью HTTP 400 Unknown Bayeux transport.

person Cosimo    schedule 21.03.2019