Debug and test SockJS server support
This commit is contained in:
parent
41153efd03
commit
4ad6091510
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 {
|
|
@ -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
|
|
@ -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());
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ package org.springframework.websocket;
|
|||
*/
|
||||
public interface WebSocketSession {
|
||||
|
||||
boolean isOpen();
|
||||
|
||||
void sendText(String text) throws Exception;
|
||||
|
||||
void close();
|
||||
|
|
|
@ -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);
|
|
@ -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
|
|
@ -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) {
|
||||
|
|
|
@ -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>();
|
||||
|
||||
|
|
Loading…
Reference in New Issue