Как прокси / зеркало URL-адреса подключения Websocket в Spring MVC? - PullRequest
0 голосов
/ 18 октября 2018

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

(Базовая справка: это веб-сервер Spring MVC Java, расположенный на той же машине, что и приложение Shiny. Если возможно, я бы хотел избежать перехода на Spring Boot.)

Код успешно отражает всесодержимое Shiny от localhost:3305 до localhost:8080/project/shiny-proxy, КРОМЕ для URL-адреса подключения к веб-сокету: ws://localhost:8080/project/shiny-proxy/websocket/ необходимо сопоставить с ws://localhost:3305/websocket/.http://localhost:3305/websocket/ возвращает жестко закодированную HTML-страницу «Не найдено» при посещении ее в Chrome, поэтому запрос с использованием префикса http:// вряд ли будет работать каким-либо способом.

Обратите внимание, что я в надежде , что, если я смогу установить соединение между клиентом и ws://localhost:3305/websocket/, коду Java не потребуется обрабатывать какие-либо сообщения Websocket между ними.

Вот код контроллерадо сих пор, основываясь на https://stackoverflow.com/a/23736527/7376471:

private static final RestTemplate restTemplate = new RestTemplate(
    /* specific HttpRequestFactory here */);

@RequestMapping(path = "/shiny-proxy/**")
public ResponseEntity<String> mirrorRest(@RequestBody(required = false) String body,
        HttpMethod method, HttpServletRequest request) throws URISyntaxException {
    String path = StringUtils.removeStart(request.getRequestURI(), "/project/shiny-proxy");
    boolean websocket = false;
    URI uri;
    if (path.endsWith("/websocket/")) {
        websocket = true;
        // restore the ws:// that the request URL started with after Spring MVC makes it http://
        uri = new URI("ws", null, "localhost", 3305, path, request.getQueryString(), null);
    } else {
        uri = new URI(request.getScheme(), null, "localhost", 3305, path, request.getQueryString(), null);
    }
    if (websocket) {
        System.out.println(request.getRequestURL().toString());
        System.out.println(request.getRequestURI());
        System.out.println(path);
        System.out.println(uri);
    }

    HttpHeaders headers = new HttpHeaders();
    if (path.endsWith(".css.map")) { // special handling for unusual content types from Shiny
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
    }
    HttpEntity<String> httpEntity = new HttpEntity<>(body, headers);
    ResponseEntity<String> ret = null;
    try {
        ret = restTemplate.exchange(uri, method, httpEntity, String.class);
    } catch (Exception e) {
        System.out.println(request.getRequestURL().toString());
        System.out.println(request.getRequestURI());
        System.out.println(path);
        System.out.println(uri);
        e.printStackTrace();
    }

    if (websocket) {
        System.out.println("ResponseEntity headers: " + ret.getHeaders());
    }
    return ret;
}

, но я не могу найти ни одного HttpRequestFactory, который работает с ws:// URL (многие из них преобразуют URI в java.net.URL, которые не 't не поддерживает ws: //, а другие, которые я тестировал, не могут обработать ws: // в рефлексивном коде), и даже если бы я мог, я не уверен, что возвращение ResponseEntity будет работать даже для ws-соединений.

Так что мой вопрос в том, существует ли ЛЮБОЙ способ заставить контроллер корректно установить соединение websocket между клиентом и localhost: 3305 по URL-адресу запроса ws: //, или я должен отказаться от идеи RestTemplate и попробоватьнастроил прокси как Nginx вместо?

1 Ответ

0 голосов
/ 20 октября 2018

Оказалось, что решение с использованием настроенного прокси в моем случае было невероятно простым: включите Include conf/extra/httpd-vhosts.conf в /opt/bitnami/apache2/conf/httpd.conf,

и установите для содержимого httpd-vhosts.conf значение:

<VirtualHost *:80>
  RewriteEngine on
  RewriteRule /project/shiny-proxy/websocket/(.*) ws://localhost:3305/websocket/$1 [P,L]
</VirtualHost>

Конфигурация Битнами по умолчанию настолько хороша, что никаких других изменений не потребовалось.

...