Предотвратить подключение через веб-сокет до установления

Наше приложение использует веб-сокеты во встроенном причале. Клиенты передают заголовок http, содержащий идентификатор. Что мы пытаемся сделать, так это заблокировать соединения, если клиент с таким же идентификатором уже подключен. И нет, мы не говорим здесь об аутентификации пользователя.

Единственный способ сделать это, известный нам в настоящее время, — реализовать эту проверку в @OnOpen-Callback Endpoint. Проблема в том, что этот метод вызывается только после того, как соединение уже установлено. Таким образом, состояние подключения второго клиента переключается.

Вместо этого мы хотим выполнить проверку до того, как соединение будет установлено. Мы думали об использовании ServletFilter, но согласно ответу другого вопрос они не поддерживаются для связи через веб-сокет.

Есть ли способ для сервера предотвратить установление соединения через веб-сокет на основе произвольного условия?


person Steven Pessall    schedule 18.03.2016    source источник
comment
Очень хотелось бы узнать изменилось ли что-то спустя 4 года? У меня такой же вопрос   -  person DubZ    schedule 05.08.2020


Ответы (1)


Таким образом, кажется, что правильный способ - создать исключение RuntimeException в пользовательском классе Configurator. По крайней мере, так они делают это в примерах с пристанью:

https://github.com/eclipse/jetty.project/blob/master/jetty-websocket/javax-websocket-server-impl/src/test/java/examples/MyAuthedConfigurator.java

Это все еще не идеальное решение, так как нет возможности отправить собственный статус http или код закрытия веб-сокета. На стороне клиента это приведет к общей трассировке стека:

java.io.IOException: Connect failure
    at org.eclipse.jetty.websocket.jsr356.ClientContainer.connect(ClientContainer.java:157)
    at org.eclipse.jetty.websocket.jsr356.ClientContainer.connectToServer(ClientContainer.java:180)
    at kam.cpush.ClientTestEndPoint.connect(ClientTestEndPoint.java:169)
    at kam.cpush.ClientTestEndPoint.connect(ClientTestEndPoint.java:155)
    at kam.cproxy.integrationtest.DuplicateControlChannelIT.connectToProxy(DuplicateControlChannelIT.java:72)
    at kam.cproxy.integrationtest.DuplicateControlChannelIT.testDuplicateChannelNotAllowed(DuplicateControlChannelIT.java:50)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
    at org.testng.TestRunner.privateRun(TestRunner.java:767)
    at org.testng.TestRunner.run(TestRunner.java:617)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
    at org.testng.SuiteRunner.run(SuiteRunner.java:240)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
    at org.testng.TestNG.run(TestNG.java:1057)
    at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:115)
    at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:205)
    at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:108)
    at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:111)
    at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
Caused by: org.eclipse.jetty.websocket.api.UpgradeException: Didn't switch protocols
    at org.eclipse.jetty.websocket.client.io.UpgradeConnection.validateResponse(UpgradeConnection.java:314)
    at org.eclipse.jetty.websocket.client.io.UpgradeConnection.read(UpgradeConnection.java:241)
    at org.eclipse.jetty.websocket.client.io.UpgradeConnection.onFillable(UpgradeConnection.java:163)
    at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
    at java.lang.Thread.run(Thread.java:745)
person Steven Pessall    schedule 18.03.2016
comment
Это вина чрезмерно упрощенного API JSR-356 (javax.websocket), а не Jetty. Если вы используете Native Jetty WebSocket API, вы можете возвращать коды состояния HTTP и еще много чего в своей собственной реализации WebSocketCreator. - person Joakim Erdfelt; 18.03.2016