Я почти закончил Как я могу встроить блестящее приложение на стороне сервера в 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 вместо?