Debug and test SockJS server support

This commit is contained in:
Rossen Stoyanchev 2013-04-05 16:34:33 -04:00
parent 41153efd03
commit 4ad6091510
20 changed files with 229 additions and 83 deletions

View File

@ -515,6 +515,7 @@ project("spring-websocket") {
compile(project(":spring-core"))
compile(project(":spring-context"))
compile(project(":spring-web"))
optional(project(":spring-webmvc"))
optional("org.apache.tomcat:tomcat-servlet-api:8.0-SNAPSHOT") // TODO: replace with "javax.servlet:javax.servlet-api"
optional("org.apache.tomcat:tomcat-websocket-api:8.0-SNAPSHOT") // TODO: replace with "javax.websocket:javax.websocket-api"

View File

@ -17,12 +17,9 @@
package org.springframework.sockjs.server;
import java.io.EOFException;
import java.io.IOException;
import java.util.Date;
import java.util.concurrent.ScheduledFuture;
import org.springframework.sockjs.server.SockJsConfiguration;
import org.springframework.sockjs.server.SockJsFrame;
import org.springframework.sockjs.SockJsHandler;
import org.springframework.sockjs.SockJsSession;
import org.springframework.sockjs.SockJsSessionSupport;

View File

@ -32,9 +32,7 @@ import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.sockjs.SockJsHandler;
import org.springframework.sockjs.TransportType;
import org.springframework.sockjs.server.support.DefaultTransportHandlerRegistrar;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
@ -56,7 +54,7 @@ public abstract class AbstractSockJsService implements SockJsConfiguration {
private static final int ONE_YEAR = 365 * 24 * 60 * 60;
private String sockJsServiceName = getClass().getSimpleName() + "@" + Integer.toHexString(hashCode());
private final String prefix;
private String clientLibraryUrl = "https://d1fxtkz8shb9d2.cloudfront.net/sockjs-0.3.4.min.js";
@ -78,31 +76,28 @@ public abstract class AbstractSockJsService implements SockJsConfiguration {
/**
* Class constructor...
*
* @param prefix the path prefix for the SockJS service. All requests with a path
* that begins with the specified prefix will be handled by this service. In a
* Servlet container this is the path within the current servlet mapping.
*/
public AbstractSockJsService() {
public AbstractSockJsService(String prefix) {
Assert.hasText(prefix, "prefix is required");
this.prefix = prefix;
this.heartbeatScheduler = createScheduler("SockJs-heartbeat-");
}
protected TaskScheduler createScheduler(String threadNamePrefix) {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setThreadNamePrefix(threadNamePrefix);
scheduler.afterPropertiesSet();
return scheduler;
}
/**
* A unique name for the service, possibly the prefix at which it is deployed.
* Used mainly for logging purposes.
* The path prefix to which the SockJS service is mapped.
*/
public void setSockJsServiceName(String serviceName) {
this.sockJsServiceName = serviceName;
}
/**
* The SockJS service name.
* @see #setSockJsServiceName(String)
*/
public String getSockJsServiceName() {
return this.sockJsServiceName;
public String getPrefix() {
return this.prefix;
}
/**
@ -178,9 +173,8 @@ public abstract class AbstractSockJsService implements SockJsConfiguration {
this.heartbeatScheduler = heartbeatScheduler;
}
public AbstractSockJsService setDisconnectDelay(long disconnectDelay) {
public void setDisconnectDelay(long disconnectDelay) {
this.disconnectDelay = disconnectDelay;
return this;
}
public long getDisconnectDelay() {
@ -193,9 +187,8 @@ public abstract class AbstractSockJsService implements SockJsConfiguration {
* <p>
* The default value is "true".
*/
public AbstractSockJsService setWebSocketsEnabled(boolean webSocketsEnabled) {
public void setWebSocketsEnabled(boolean webSocketsEnabled) {
this.webSocketsEnabled = webSocketsEnabled;
return this;
}
/**
@ -212,9 +205,8 @@ public abstract class AbstractSockJsService implements SockJsConfiguration {
* heartbeats, only raw WebSocket protocol. This property allows setting a
* handler for requests for raw WebSocket communication.
*/
public AbstractSockJsService setWebsocketHandler(HandshakeRequestHandler handshakeRequestHandler) {
public void setWebsocketHandler(HandshakeRequestHandler handshakeRequestHandler) {
this.handshakeRequestHandler = handshakeRequestHandler;
return this;
}

View File

@ -29,38 +29,41 @@ import com.fasterxml.jackson.databind.ObjectMapper;
/**
* An implementation of {@link WebSocketHandler} supporting the SockJS protocol.
* Methods merely delegate to a {@link StandardWebSocketServerSession}.
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public class WebSocketSockJsHandlerAdapter implements WebSocketHandler {
public class SockJsWebSocketHandler implements WebSocketHandler {
private static final Log logger = LogFactory.getLog(WebSocketSockJsHandlerAdapter.class);
private static final Log logger = LogFactory.getLog(SockJsWebSocketHandler.class);
private final SockJsWebSocketSessionAdapter sockJsSession;
private final StandardWebSocketServerSession sockJsSession;
// TODO: the JSON library used must be configurable
private final ObjectMapper objectMapper = new ObjectMapper();
public WebSocketSockJsHandlerAdapter(SockJsWebSocketSessionAdapter sockJsSession) {
public SockJsWebSocketHandler(StandardWebSocketServerSession sockJsSession) {
this.sockJsSession = sockJsSession;
}
@Override
public void newSession(WebSocketSession webSocketSession) throws Exception {
logger.debug("WebSocket connection established");
webSocketSession.sendText(SockJsFrame.openFrame().getContent());
if (logger.isDebugEnabled()) {
logger.debug("New session: " + webSocketSession);
}
this.sockJsSession.setWebSocketSession(webSocketSession);
}
@Override
public void handleTextMessage(WebSocketSession session, String message) throws Exception {
if (logger.isDebugEnabled()) {
logger.debug("Received payload " + message + " for " + sockJsSession);
if (logger.isTraceEnabled()) {
logger.trace("Received payload " + message + " for " + sockJsSession);
}
if (StringUtils.isEmpty(message)) {
logger.debug("Ignoring empty payload");
logger.trace("Ignoring empty payload");
return;
}
try {

View File

@ -27,26 +27,27 @@ import org.springframework.websocket.WebSocketSession;
* @author Rossen Stoyanchev
* @since 4.0
*/
public class SockJsWebSocketSessionAdapter extends AbstractServerSession {
public class StandardWebSocketServerSession extends AbstractServerSession {
private static Log logger = LogFactory.getLog(SockJsWebSocketSessionAdapter.class);
private static Log logger = LogFactory.getLog(StandardWebSocketServerSession.class);
private WebSocketSession webSocketSession;
public SockJsWebSocketSessionAdapter(String sessionId, SockJsHandler delegate, SockJsConfiguration sockJsConfig) {
public StandardWebSocketServerSession(String sessionId, SockJsHandler delegate, SockJsConfiguration sockJsConfig) {
super(sessionId, delegate, sockJsConfig);
}
public void setWebSocketSession(WebSocketSession webSocketSession) throws Exception {
this.webSocketSession = webSocketSession;
webSocketSession.sendText(SockJsFrame.openFrame().getContent());
scheduleHeartbeat();
connectionInitialized();
}
@Override
public boolean isActive() {
return (this.webSocketSession != null);
return ((this.webSocketSession != null) && this.webSocketSession.isOpen());
}
@Override

View File

@ -64,7 +64,8 @@ public class DefaultSockJsService extends AbstractSockJsService implements Trans
* Class constructor...
*
*/
public DefaultSockJsService(SockJsHandler sockJsHandler) {
public DefaultSockJsService(String prefix, SockJsHandler sockJsHandler) {
super(prefix);
Assert.notNull(sockJsHandler, "sockJsHandler is required");
this.sockJsHandler = sockJsHandler;
this.sessionTimeoutScheduler = createScheduler("SockJs-sessionTimeout-");
@ -105,23 +106,23 @@ public class DefaultSockJsService extends AbstractSockJsService implements Trans
try {
int count = sessions.size();
if (logger.isTraceEnabled() && (count != 0)) {
logger.trace("Checking " + count + " session(s) for timeouts [" + getSockJsServiceName() + "]");
logger.trace("Checking " + count + " session(s) for timeouts [" + getPrefix() + "]");
}
for (SockJsSessionSupport session : sessions.values()) {
if (session.getTimeSinceLastActive() > getDisconnectDelay()) {
if (logger.isTraceEnabled()) {
logger.trace("Removing " + session + " for [" + getSockJsServiceName() + "]");
logger.trace("Removing " + session + " for [" + getPrefix() + "]");
}
session.close();
sessions.remove(session.getId());
}
}
if (logger.isTraceEnabled() && (count != 0)) {
logger.trace(sessions.size() + " remaining session(s) [" + getSockJsServiceName() + "]");
logger.trace(sessions.size() + " remaining session(s) [" + getPrefix() + "]");
}
}
catch (Throwable t) {
logger.error("Failed to complete session timeout checks for [" + getSockJsServiceName() + "]", t);
logger.error("Failed to complete session timeout checks for [" + getPrefix() + "]", t);
}
}
}, getDisconnectDelay());

View File

@ -21,6 +21,7 @@ import org.springframework.sockjs.server.transport.EventSourceTransportHandler;
import org.springframework.sockjs.server.transport.HtmlFileTransportHandler;
import org.springframework.sockjs.server.transport.JsonpPollingTransportHandler;
import org.springframework.sockjs.server.transport.JsonpTransportHandler;
import org.springframework.sockjs.server.transport.WebSocketTransportHandler;
import org.springframework.sockjs.server.transport.XhrPollingTransportHandler;
import org.springframework.sockjs.server.transport.XhrStreamingTransportHandler;
import org.springframework.sockjs.server.transport.XhrTransportHandler;
@ -36,6 +37,8 @@ public class DefaultTransportHandlerRegistrar implements TransportHandlerRegistr
public void registerTransportHandlers(TransportHandlerRegistry registry) {
registry.registerHandler(new WebSocketTransportHandler());
registry.registerHandler(new XhrPollingTransportHandler());
registry.registerHandler(new XhrTransportHandler());

View File

@ -0,0 +1,70 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.sockjs.server.support;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.sockjs.server.AbstractSockJsService;
import org.springframework.web.servlet.handler.AbstractHandlerMapping;
/**
* A Spring MVC HandlerMapping matching requests to SockJS services by prefix.
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public class SockJsServiceHandlerMapping extends AbstractHandlerMapping {
private static Log logger = LogFactory.getLog(SockJsServiceHandlerMapping.class);
private final List<AbstractSockJsService> sockJsServices;
public SockJsServiceHandlerMapping(AbstractSockJsService... sockJsServices) {
this.sockJsServices = Arrays.asList(sockJsServices);
}
@Override
protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
if (logger.isDebugEnabled()) {
logger.debug("Looking for SockJS service match to path " + lookupPath);
}
for (AbstractSockJsService service : this.sockJsServices) {
if (lookupPath.startsWith(service.getPrefix())) {
if (logger.isDebugEnabled()) {
logger.debug("Matched to " + service);
}
String sockJsPath = lookupPath.substring(service.getPrefix().length());
return new SockJsServiceHttpRequestHandler(sockJsPath, service);
}
}
if (logger.isDebugEnabled()) {
logger.debug("Did not find a match");
}
return null;
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.sockjs.server.support;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.server.AsyncServletServerHttpRequest;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.sockjs.server.AbstractSockJsService;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.util.NestedServletException;
/**
* A Spring MVC {@link HttpRequestHandler} wrapping the invocation of a SockJS service.
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public class SockJsServiceHttpRequestHandler implements HttpRequestHandler {
private final String sockJsPath;
private final AbstractSockJsService sockJsService;
public SockJsServiceHttpRequestHandler(String sockJsPath, AbstractSockJsService sockJsService) {
this.sockJsService = sockJsService;
this.sockJsPath = sockJsPath;
}
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServerHttpRequest httpRequest = new AsyncServletServerHttpRequest(request, response);
ServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
try {
this.sockJsService.handleRequest(httpRequest, httpResponse, this.sockJsPath);
}
catch (Exception ex) {
// TODO
throw new NestedServletException("SockJS service failure", ex);
}
}
}

View File

@ -15,6 +15,8 @@
*/
package org.springframework.sockjs.server.transport;
import java.io.IOException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.http.MediaType;
@ -37,14 +39,19 @@ public abstract class AbstractHttpSendingTransportHandler implements TransportHa
@Override
public void handleRequest(ServerHttpRequest request, ServerHttpResponse response, SockJsSessionSupport session)
throws Exception {
AbstractHttpServerSession httpServerSession = (AbstractHttpServerSession) session;
public final void handleRequest(ServerHttpRequest request, ServerHttpResponse response,
SockJsSessionSupport session) throws Exception {
// Set content type before writing
response.getHeaders().setContentType(getContentType());
AbstractHttpServerSession httpServerSession = (AbstractHttpServerSession) session;
handleRequestInternal(request, response, httpServerSession);
}
protected void handleRequestInternal(ServerHttpRequest request, ServerHttpResponse response,
AbstractHttpServerSession httpServerSession) throws Exception, IOException {
if (httpServerSession.isNew()) {
handleNewSession(request, response, httpServerSession);
}

View File

@ -20,7 +20,6 @@ import java.io.IOException;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.sockjs.SockJsHandler;
import org.springframework.sockjs.SockJsSessionSupport;
import org.springframework.sockjs.server.SockJsConfiguration;
@ -39,12 +38,11 @@ public abstract class AbstractStreamingTransportHandler extends AbstractHttpSend
}
@Override
public void handleRequest(ServerHttpRequest request, ServerHttpResponse response, SockJsSessionSupport session)
throws Exception {
public void handleRequestInternal(ServerHttpRequest request, ServerHttpResponse response,
AbstractHttpServerSession session) throws Exception {
writePrelude(request, response);
super.handleRequest(request, response, session);
super.handleRequestInternal(request, response, session);
}
protected abstract void writePrelude(ServerHttpRequest request, ServerHttpResponse response)

View File

@ -22,7 +22,6 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.sockjs.SockJsSessionSupport;
import org.springframework.sockjs.TransportType;
import org.springframework.sockjs.server.SockJsFrame.DefaultFrameFormat;
import org.springframework.sockjs.server.SockJsFrame.FrameFormat;
@ -78,8 +77,8 @@ public class HtmlFileTransportHandler extends AbstractStreamingTransportHandler
}
@Override
public void handleRequest(ServerHttpRequest request, ServerHttpResponse response, SockJsSessionSupport session)
throws Exception {
public void handleRequestInternal(ServerHttpRequest request, ServerHttpResponse response,
AbstractHttpServerSession session) throws Exception {
String callback = request.getQueryParams().getFirst("c");
if (! StringUtils.hasText(callback)) {
@ -87,8 +86,7 @@ public class HtmlFileTransportHandler extends AbstractStreamingTransportHandler
response.getBody().write("\"callback\" parameter required".getBytes("UTF-8"));
return;
}
super.handleRequest(request, response, session);
super.handleRequestInternal(request, response, session);
}
@Override

View File

@ -22,7 +22,6 @@ import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.sockjs.SockJsHandler;
import org.springframework.sockjs.SockJsSessionSupport;
import org.springframework.sockjs.TransportType;
import org.springframework.sockjs.server.SockJsConfiguration;
import org.springframework.sockjs.server.SockJsFrame;
@ -56,8 +55,8 @@ public class JsonpPollingTransportHandler extends AbstractHttpSendingTransportHa
}
@Override
public void handleRequest(ServerHttpRequest request, ServerHttpResponse response, SockJsSessionSupport session)
throws Exception {
public void handleRequestInternal(ServerHttpRequest request, ServerHttpResponse response,
AbstractHttpServerSession session) throws Exception {
String callback = request.getQueryParams().getFirst("c");
if (! StringUtils.hasText(callback)) {
@ -65,7 +64,6 @@ public class JsonpPollingTransportHandler extends AbstractHttpSendingTransportHa
response.getBody().write("\"callback\" parameter required".getBytes("UTF-8"));
return;
}
super.handleRequest(request, response, session);
}

View File

@ -43,7 +43,8 @@ public class StreamingHttpServerSession extends AbstractHttpServerSession {
this.byteCount += frame.getContentBytes().length + 1;
if (logger.isTraceEnabled()) {
logger.trace(this.byteCount + " bytes written, " + getMessageCache().size() + " more messages");
logger.trace(this.byteCount + " bytes written so far, "
+ getMessageCache().size() + " more messages not flushed");
}
if (this.byteCount >= getSockJsConfig().getStreamBytesLimit()) {
if (logger.isTraceEnabled()) {

View File

@ -22,9 +22,9 @@ import org.springframework.sockjs.SockJsHandler;
import org.springframework.sockjs.SockJsSessionSupport;
import org.springframework.sockjs.TransportType;
import org.springframework.sockjs.server.SockJsConfiguration;
import org.springframework.sockjs.server.SockJsWebSocketSessionAdapter;
import org.springframework.sockjs.server.StandardWebSocketServerSession;
import org.springframework.sockjs.server.TransportHandler;
import org.springframework.sockjs.server.WebSocketSockJsHandlerAdapter;
import org.springframework.sockjs.server.SockJsWebSocketHandler;
import org.springframework.websocket.server.HandshakeRequestHandler;
import org.springframework.websocket.server.endpoint.EndpointHandshakeRequestHandler;
@ -44,15 +44,15 @@ public class WebSocketTransportHandler implements TransportHandler {
@Override
public SockJsSessionSupport createSession(String sessionId, SockJsHandler handler, SockJsConfiguration config) {
return new SockJsWebSocketSessionAdapter(sessionId, handler, config);
return new StandardWebSocketServerSession(sessionId, handler, config);
}
@Override
public void handleRequest(ServerHttpRequest request, ServerHttpResponse response, SockJsSessionSupport session)
throws Exception {
SockJsWebSocketSessionAdapter sockJsSession = (SockJsWebSocketSessionAdapter) session;
WebSocketSockJsHandlerAdapter webSocketHandler = new WebSocketSockJsHandlerAdapter(sockJsSession);
StandardWebSocketServerSession sockJsSession = (StandardWebSocketServerSession) session;
SockJsWebSocketHandler webSocketHandler = new SockJsWebSocketHandler(sockJsSession);
HandshakeRequestHandler handshakeRequestHandler = new EndpointHandshakeRequestHandler(webSocketHandler);
handshakeRequestHandler.doHandshake(request, response);
}

View File

@ -25,6 +25,8 @@ package org.springframework.websocket;
*/
public interface WebSocketSession {
boolean isOpen();
void sendText(String text) throws Exception;
void close();

View File

@ -22,21 +22,27 @@ import org.springframework.websocket.WebSocketSession;
/**
* A {@link WebSocketSession} that delegates to a {@link javax.websocket.Session}.
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public class WebSocketStandardSessionAdapter implements WebSocketSession {
public class StandardWebSocketSession implements WebSocketSession {
private static Log logger = LogFactory.getLog(WebSocketStandardSessionAdapter.class);
private static Log logger = LogFactory.getLog(StandardWebSocketSession.class);
private javax.websocket.Session session;
public WebSocketStandardSessionAdapter(javax.websocket.Session session) {
public StandardWebSocketSession(javax.websocket.Session session) {
this.session = session;
}
@Override
public boolean isOpen() {
return ((this.session != null) && this.session.isOpen());
}
@Override
public void sendText(String text) throws Exception {
logger.trace("Sending text message: " + text);

View File

@ -32,28 +32,31 @@ import org.springframework.websocket.WebSocketHandler;
/**
* An {@link Endpoint} that delegates to a {@link WebSocketHandler}.
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public class StandardWebSocketHandlerAdapter extends Endpoint {
public class WebSocketHandlerEndpoint extends Endpoint {
private static Log logger = LogFactory.getLog(StandardWebSocketHandlerAdapter.class);
private static Log logger = LogFactory.getLog(WebSocketHandlerEndpoint.class);
private final WebSocketHandler webSocketHandler;
private final Map<String, WebSocketSession> sessionMap = new ConcurrentHashMap<String, WebSocketSession>();
public StandardWebSocketHandlerAdapter(WebSocketHandler webSocketHandler) {
public WebSocketHandlerEndpoint(WebSocketHandler webSocketHandler) {
this.webSocketHandler = webSocketHandler;
}
@Override
public void onOpen(javax.websocket.Session session, EndpointConfig config) {
logger.debug("New WebSocket session: " + session);
if (logger.isDebugEnabled()) {
logger.debug("New session: " + session);
}
try {
WebSocketSession webSocketSession = new WebSocketStandardSessionAdapter(session);
WebSocketSession webSocketSession = new StandardWebSocketSession(session);
this.sessionMap.put(session.getId(), webSocketSession);
session.addMessageHandler(new StandardMessageHandler(session.getId()));
this.webSocketHandler.newSession(webSocketSession);
@ -75,7 +78,6 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
this.sessionMap.remove(id);
int code = closeReason.getCloseCode().getCode();
String reason = closeReason.getReasonPhrase();
webSocketSession.close(code, reason);
this.webSocketHandler.sessionClosed(webSocketSession, code, reason);
}
catch (Throwable ex) {
@ -119,7 +121,7 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
}
try {
WebSocketSession session = getSession(this.sessionId);
StandardWebSocketHandlerAdapter.this.webSocketHandler.handleTextMessage(session, message);
WebSocketHandlerEndpoint.this.webSocketHandler.handleTextMessage(session, message);
}
catch (Throwable ex) {
// TODO

View File

@ -23,7 +23,7 @@ import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.util.ClassUtils;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.endpoint.StandardWebSocketHandlerAdapter;
import org.springframework.websocket.endpoint.WebSocketHandlerEndpoint;
import org.springframework.websocket.server.AbstractHandshakeRequestHandler;
@ -43,7 +43,7 @@ public class EndpointHandshakeRequestHandler extends AbstractHandshakeRequestHan
public EndpointHandshakeRequestHandler(WebSocketHandler webSocketHandler) {
this(new StandardWebSocketHandlerAdapter(webSocketHandler));
this(new WebSocketHandlerEndpoint(webSocketHandler));
}
public EndpointHandshakeRequestHandler(Endpoint endpoint) {

View File

@ -36,14 +36,14 @@ import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.websocket.endpoint.StandardWebSocketHandlerAdapter;
import org.springframework.websocket.endpoint.WebSocketHandlerEndpoint;
/**
* An implementation of {@link javax.websocket.server.ServerEndpointConfig} that also
* holds the target {@link javax.websocket.Endpoint} as a reference or a bean name.
* The target can also be {@link org.springframework.websocket.WebSocketHandler}, in
* which case it will be adapted via {@link StandardWebSocketHandlerAdapter}.
* which case it will be adapted via {@link WebSocketHandlerEndpoint}.
*
* <p>
* Beans of this type are detected by {@link EndpointExporter} and
@ -60,9 +60,9 @@ public class EndpointRegistration implements ServerEndpointConfig, BeanFactoryAw
private final Object endpointBean;
private List<Class<? extends Encoder>> encoders;
private List<Class<? extends Encoder>> encoders = new ArrayList<Class<? extends Encoder>>();
private List<Class<? extends Decoder>> decoders;
private List<Class<? extends Decoder>> decoders = new ArrayList<Class<? extends Decoder>>();
private List<String> subprotocols = new ArrayList<String>();