I'm having some troubles running a simple application using Spring WebSockets 4.1.6, Tomcat 7.0.54 and Apache 2.4.16 as Web Server.
我使用Spring WebSockets 4.1.6,Tomcat 7.0.54和Apache 2.4.16作為Web服務器運行一個簡單的應用程序時遇到了一些麻煩。
I have read a lot of posts in internet, and I don't know what's happening. The server starts without problems. I have an index.html published in my server project that starts a WebSocket connection.
我在互聯網上看過很多帖子,我不知道發生了什么。服務器啟動沒有問題。我在我的服務器項目中發布了一個index.html,它啟動了一個WebSocket連接。
If I access to this file directly from Tomcat, it works perfectly.
如果我直接從Tomcat訪問這個文件,它可以很好地工作。
http://localhost:8080/myserver/messaging/index.html
But if I access to this file from Apache Server, it doesn't work.
但是,如果我從Apache Server訪問此文件,它將無法正常工作。
http://localhost/messages/messaging/index.html
In my Apache Server I have configured a proxy pass:
在我的Apache服務器中,我配置了一個代理傳遞:
ProxyPass /messages http://localhost:8080/myserver
ProxyPassReverse /messages http://localhost:8080/myserver
My server WebSocket configuration looks as follows:
我的服務器WebSocket配置如下所示:
@Configuration
@EnableWebSocketMessageBroker
public class PuiWebSocketConfig extends
AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.setApplicationDestinationPrefixes("/app");
config.enableSimpleBroker("/user", "/topic");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/puimessaging").withSockJS();
}
}
And my client does the connection as follows:
我的客戶端連接如下:
function connect() {
var socket = new SockJS('/server/puimessaging');
var stompClient = Stomp.over(socket);
var headers = {
puiSessionId : 'a1234567890z'
};
stompClient.connect(headers, function(frame) {
setConnected(true);
stompClient.subscribe('/user/a1234567890z/response', function(data) {
...
});
});
}
The server throws an error saying that I need to enable Async support, but I don't know what to do.
服務器拋出一個錯誤,說我需要啟用異步支持,但我不知道該怎么做。
Async support must be enabled on a servlet and for all filters involved
in async request processing. This is done in Java code using the Servlet
API or by adding "<async-supported>true</async-supported>" to servlet and
filter declarations in web.xml. Also you must use a Servlet 3.0+ container
I tried to add the property on my web.xml file, but it doesn't work:
我試圖在我的web.xml文件中添加該屬性,但它不起作用:
<servlet>
<servlet-name>spring-mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Any idea?
Thanks in advance.
提前致謝。
Marc
I get it working, not via WebSockets but via xhr_streaming. My configuration looks as follows:
我得到它的工作,不是通過WebSockets,而是通過xhr_streaming。我的配置如下:
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="webApp" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<servlet-name>spring-mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Tomcat (server.xml):
<Connector URIEncoding="UTF-8" connectionTimeout="20000"
port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
redirectPort="8443" />
Apache httpd:
...
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_express_module modules/mod_proxy_express.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
# LoadModule proxy_html_module modules/mod_proxy_html.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_scgi_module modules/mod_proxy_scgi.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
...
ProxyPass /pideweb-gijon http://localhost:8080/pideweb_gijon
ProxyPassReverse /pideweb-gijon http://localhost:8080/pideweb_gijon
ProxyPass /pideweb-gijon/endpointpuisocket/ ws://localhost:8080/pideweb_gijon/endpointpuisocket/
ProxyPassReverse /pideweb-gijon/endpointpuisocket/ ws://localhost:8080/pideweb_gijon/endpointpuisocket/
Spring Configuration:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Autowired
private WebSocketService websocketService;
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.setApplicationDestinationPrefixes("/app");
config.enableSimpleBroker("/user", "/topic");
// config.setUserDestinationPrefix("/user");
// config.enableSimpleBroker("/queue", "/topic");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/endpointpuisocket").withSockJS();
}
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
ChannelInterceptorAdapter interceptor = new ChannelInterceptorAdapter() {
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
// store or remove the Session ID in the list depending on the
// message is for Connecting or Disconnecting
StompHeaderAccessor accessor = StompHeaderAccessor
.wrap(message);
StompCommand command = accessor.getCommand();
List<String> headersSessionId = accessor
.getNativeHeader("puiSessionId");
if (!CollectionUtils.isEmpty(headersSessionId)) {
String sessionId = headersSessionId.get(0);
switch (command) {
case CONNECT:
// add the session ID
websocketService.addSession(sessionId);
break;
case DISCONNECT:
// remove the session ID
websocketService.removeSession(sessionId);
break;
default:
break;
}
}
return message;
}
};
registration.setInterceptors(interceptor);
}
}
Javascript Client:
function(gst) {
var url = '/pideweb-gijon/endpointpuisocket';
var socket = new SockJS(url);
var stompClient = Stomp.over(socket);
var headers = {
puiSessionId : gst
};
var self = this;
stompClient.connect(headers, function(frame) {
console.log('Connected: ' + frame);
self.stompClient.subscribe('/user/' + gst + '/response', function(data) {
console.log(data.body);
});
});
};
With this, when I enter the client, automatically tries to connect to the Server. I'm using Chrome, and this is the stack of requests:
有了這個,當我進入客戶端時,會自動嘗試連接到服務器。我正在使用Chrome,這是一堆請求:
Info request
Websocket request
XHR_streaming request
Anybody knows what could be happening with Websocket request?
有誰知道Websocket請求會發生什么?
Thanks!
For this, you need to update your tomcat connector, go in your tomcat directory --> conf --> server.xml. Locate the below line :
為此,您需要更新tomcat連接器,進入tomcat目錄 - > conf - > server.xml。找到以下行:
<Connector connectionTimeout="20000" maxThreads="1000" port="8080" protocol="org.apache.coyote.http1.1"/>
Something similar it should be, notice the protocol, and change it to :
它應該是類似的東西,注意協議,並將其更改為:
<Connector connectionTimeout="20000" maxThreads="1000" port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"/>
Restart your tomcat.
重啟你的tomcat。
Knowing that everything works as expected with Tomcat, there's probably a problem with your Apache configuration.
知道Tomcat的一切都按預期工作,您的Apache配置可能存在問題。
By default, Apache does not support websocket UPGRADE, you need to install+configure mod_proxy_wstunnel.
默認情況下,Apache不支持websocket UPGRADE,需要安裝+ configure mod_proxy_wstunnel。
You'll probably have to make sure that mod_proxy is in HTTP mode (i.e. not AJP) and that HTTP persistent connections are properly supported if you want the various SockJS transports to work.
您可能必須確保mod_proxy處於HTTP模式(即不是AJP),並且如果您希望各種SockJS傳輸工作,則可以正確支持HTTP持久連接。
I got the same issue and solution of @Marc Gil Sendra works for me. It need to configure Proxypass from Apache for WebSocket protocol.
我得到了同樣的問題,@ Marc Gil Sendra的解決方案適合我。它需要從Apache為WebSocket協議配置Proxypass。
ProxyPass /pideweb-gijon/endpointpuisocket/ ws://localhost:8080/pideweb_gijon/endpointpuisocket/
ProxyPass / pideweb-gijon / endpointpuisocket / ws:// localhost:8080 / pideweb_gijon / endpointpuisocket /
ProxyPassReverse /pideweb-gijon/endpointpuisocket/ ws://localhost:8080/pideweb_gijon/endpointpuisocket/
ProxyPassReverse / pideweb-gijon / endpointpuisocket / ws:// localhost:8080 / pideweb_gijon / endpointpuisocket /
I tested in Bitnami EC2 (Apache + Tomcat), the configure as bellow File config: /opt/bitnami/apache-tomcat/conf/apache-tomcat-prefix.conf
我在Bitnami EC2(Apache + Tomcat)中測試過,配置如下文件配置:/opt/bitnami/apache-tomcat/conf/apache-tomcat-prefix.conf
<Location /AppContext/endpointpuisocket> ProxyPass ws://localhost:8080/AppContext/endpointpuisocket </Location>
本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2015/05/12/64d739139f0004b482125f53c2a26be.html。