Fix minor issue and polish

This commit is contained in:
Rossen Stoyanchev
2013-04-24 13:29:08 -04:00
parent 36148b7cb1
commit 34c95034d8
10 changed files with 66 additions and 37 deletions

View File

@@ -139,7 +139,7 @@ public abstract class AbstractSockJsSession implements WebSocketSession {
}
}
public void delegateError(Throwable ex) {
public void delegateError(Throwable ex) throws Exception {
this.handler.handleError(ex, this);
}

View File

@@ -36,6 +36,7 @@ import org.springframework.sockjs.AbstractSockJsSession;
import org.springframework.sockjs.SockJsSessionFactory;
import org.springframework.sockjs.server.AbstractSockJsService;
import org.springframework.sockjs.server.ConfigurableTransportHandler;
import org.springframework.sockjs.server.SockJsService;
import org.springframework.sockjs.server.TransportHandler;
import org.springframework.sockjs.server.TransportType;
import org.springframework.sockjs.server.transport.EventSourceTransportHandler;
@@ -54,7 +55,8 @@ import org.springframework.websocket.server.HandshakeHandler;
/**
* TODO
* A default implementation of {@link SockJsService} adding support for transport handling
* and session management.
*
* @author Rossen Stoyanchev
* @since 4.0
@@ -68,10 +70,31 @@ public class DefaultSockJsService extends AbstractSockJsService {
private ScheduledFuture sessionCleanupTask;
/**
* Create an instance with default {@link TransportHandler transport handler} types.
*
* @param taskScheduler a task scheduler for heart-beat messages and removing
* timed-out sessions; the provided TaskScheduler should be declared as a
* Spring bean to ensure it is initialized at start up and shut down when the
* application stops.
*/
public DefaultSockJsService(TaskScheduler taskScheduler) {
this(taskScheduler, null);
}
/**
* Create an instance by overriding or replacing completely the default
* {@link TransportHandler transport handler} types.
*
* @param taskScheduler a task scheduler for heart-beat messages and removing
* timed-out sessions; the provided TaskScheduler should be declared as a
* Spring bean to ensure it is initialized at start up and shut down when the
* application stops.
* @param transportHandlers the transport handlers to use (replaces the default ones);
* can be {@code null}.
* @param transportHandlerOverrides zero or more overrides to the default transport
* handler types.
*/
public DefaultSockJsService(TaskScheduler taskScheduler, Set<TransportHandler> transportHandlers,
TransportHandler... transportHandlerOverrides) {
@@ -82,7 +105,7 @@ public class DefaultSockJsService extends AbstractSockJsService {
addTransportHandlers(Arrays.asList(transportHandlerOverrides));
}
protected Set<TransportHandler> getDefaultTransportHandlers() {
protected final Set<TransportHandler> getDefaultTransportHandlers() {
Set<TransportHandler> result = new HashSet<TransportHandler>();
result.add(new XhrPollingTransportHandler());
result.add(new XhrTransportHandler());
@@ -91,14 +114,12 @@ public class DefaultSockJsService extends AbstractSockJsService {
result.add(new XhrStreamingTransportHandler());
result.add(new EventSourceTransportHandler());
result.add(new HtmlFileTransportHandler());
if (isWebSocketEnabled()) {
try {
result.add(new WebSocketTransportHandler(new DefaultHandshakeHandler()));
}
catch (Exception ex) {
if (logger.isWarnEnabled()) {
logger.warn("Failed to add default WebSocketTransportHandler: " + ex.getMessage());
}
try {
result.add(new WebSocketTransportHandler(new DefaultHandshakeHandler()));
}
catch (Exception ex) {
if (logger.isWarnEnabled()) {
logger.warn("Failed to add default WebSocketTransportHandler: " + ex.getMessage());
}
}
return result;

View File

@@ -102,7 +102,7 @@ public class SockJsWebSocketHandler implements TextMessageHandler {
}
@Override
public void handleError(Throwable exception, WebSocketSession webSocketSession) {
public void handleError(Throwable exception, WebSocketSession webSocketSession) throws Exception {
this.session.delegateError(exception);
}

View File

@@ -113,19 +113,15 @@ public final class CloseStatus {
public static final CloseStatus SERVER_ERROR = new CloseStatus(1011);
/**
* 1012 indicates that the service is restarted. A client may reconnect, and if it
* choses to do, should reconnect using a randomized delay of 5 - 30s.
* <p>See <a href="https://www.ietf.org/mail-archive/web/hybi/current/msg09649.html">
* [hybi] Additional WebSocket Close Error Codes</a>
* "1012 indicates that the service is restarted. A client may reconnect, and if it
* chooses to do, should reconnect using a randomized delay of 5 - 30s."
*/
public static final CloseStatus SERVICE_RESTARTED = new CloseStatus(1012);
/**
* 1013 indicates that the service is experiencing overload. A client should only
* "1013 indicates that the service is experiencing overload. A client should only
* connect to a different IP (when there are multiple for the target) or reconnect to
* the same IP upon user action.
* <p>See <a href="https://www.ietf.org/mail-archive/web/hybi/current/msg09649.html">
* [hybi] Additional WebSocket Close Error Codes</a>
* the same IP upon user action."
*/
public static final CloseStatus SERVICE_OVERLOAD = new CloseStatus(1013);

View File

@@ -39,6 +39,6 @@ public interface WebSocketHandler {
/**
* TODO
*/
void handleError(Throwable exception, WebSocketSession session);
void handleError(Throwable exception, WebSocketSession session) throws Exception;
}

View File

@@ -37,6 +37,9 @@ import org.springframework.websocket.WebSocketSession;
public interface WebSocketClient {
WebSocketSession doHandshake(WebSocketHandler handler,
String uriTemplate, Object... uriVariables) throws WebSocketConnectFailureException;
WebSocketSession doHandshake(HandlerProvider<WebSocketHandler> handler,
String uriTemplate, Object... uriVariables) throws WebSocketConnectFailureException;

View File

@@ -38,6 +38,7 @@ import org.springframework.websocket.client.WebSocketClient;
import org.springframework.websocket.client.WebSocketConnectFailureException;
import org.springframework.websocket.endpoint.StandardWebSocketSession;
import org.springframework.websocket.endpoint.WebSocketHandlerEndpoint;
import org.springframework.websocket.support.SimpleHandlerProvider;
/**
@@ -59,6 +60,13 @@ public class StandardWebSocketClient implements WebSocketClient {
this.webSocketContainer = container;
}
@Override
public WebSocketSession doHandshake(WebSocketHandler handler, String uriTemplate, Object... uriVariables)
throws WebSocketConnectFailureException {
return doHandshake(new SimpleHandlerProvider<WebSocketHandler>(handler), uriTemplate, uriVariables);
}
public WebSocketSession doHandshake(HandlerProvider<WebSocketHandler> handler,
String uriTemplate, Object... uriVariables) throws WebSocketConnectFailureException {

View File

@@ -67,7 +67,7 @@ public class WebSocketHandlerEndpoint extends Endpoint {
Assert.isTrue(this.sessionCount.compareAndSet(0, 1), "Unexpected connection");
if (logger.isDebugEnabled()) {
logger.debug("Client connected, javax.websocket.Session id="
logger.debug("Connection established, javax.websocket.Session id="
+ session.getId() + ", uri=" + session.getRequestURI());
}
@@ -110,7 +110,7 @@ public class WebSocketHandlerEndpoint extends Endpoint {
this.handler.afterConnectionEstablished(this.webSocketSession);
}
catch (Throwable ex) {
this.handler.handleError(ex, this.webSocketSession);
onError(session, ex);
}
}
@@ -123,7 +123,7 @@ public class WebSocketHandlerEndpoint extends Endpoint {
((TextMessageHandler) handler).handleTextMessage(textMessage, this.webSocketSession);
}
catch (Throwable ex) {
this.handler.handleError(ex, this.webSocketSession);
onError(session, ex);
}
}
@@ -136,21 +136,21 @@ public class WebSocketHandlerEndpoint extends Endpoint {
((BinaryMessageHandler) handler).handleBinaryMessage(binaryMessage, this.webSocketSession);
}
catch (Throwable ex) {
this.handler.handleError(ex, this.webSocketSession);
onError(session, ex);
}
}
@Override
public void onClose(javax.websocket.Session session, CloseReason reason) {
if (logger.isDebugEnabled()) {
logger.debug("Client disconnected, WebSocket session id=" + session.getId() + ", " + reason);
logger.debug("Connection closed, WebSocket session id=" + session.getId() + ", " + reason);
}
try {
CloseStatus closeStatus = new CloseStatus(reason.getCloseCode().getCode(), reason.getReasonPhrase());
this.handler.afterConnectionClosed(closeStatus, this.webSocketSession);
}
catch (Throwable ex) {
logger.error("Error while processing session closing", ex);
onError(session, ex);
}
finally {
this.handlerProvider.destroy(this.handler);

View File

@@ -143,7 +143,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy {
try {
this.session = new WebSocketSessionAdapter(session);
if (logger.isDebugEnabled()) {
logger.debug("Client connected, WebSocket session id="
logger.debug("Connection established, WebSocket session id="
+ this.session.getId() + ", uri=" + this.session.getURI());
}
this.handler = this.provider.getHandler();
@@ -167,7 +167,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy {
try {
CloseStatus closeStatus = new CloseStatus(statusCode, reason);
if (logger.isDebugEnabled()) {
logger.debug("Client disconnected, WebSocket session id="
logger.debug("Connection closed, WebSocket session id="
+ this.session.getId() + ", " + closeStatus);
}
this.handler.afterConnectionClosed(closeStatus, this.session);

View File

@@ -44,25 +44,26 @@ import org.springframework.websocket.support.SimpleHandlerProvider;
*/
public class WebSocketHttpRequestHandler implements HttpRequestHandler {
private HandshakeHandler handshakeHandler;
private final HandshakeHandler handshakeHandler;
private final HandlerProvider<WebSocketHandler> handlerProvider;
public WebSocketHttpRequestHandler(WebSocketHandler webSocketHandler) {
Assert.notNull(webSocketHandler, "webSocketHandler is required");
this.handlerProvider = new SimpleHandlerProvider<WebSocketHandler>(webSocketHandler);
this.handshakeHandler = new DefaultHandshakeHandler();
this(new SimpleHandlerProvider<WebSocketHandler>(webSocketHandler));
}
public WebSocketHttpRequestHandler( HandlerProvider<WebSocketHandler> handlerProvider) {
Assert.notNull(handlerProvider, "handlerProvider is required");
this.handlerProvider = handlerProvider;
this(handlerProvider, new DefaultHandshakeHandler());
}
public void setHandshakeHandler(HandshakeHandler handshakeHandler) {
public WebSocketHttpRequestHandler( HandlerProvider<WebSocketHandler> handlerProvider,
HandshakeHandler handshakeHandler) {
Assert.notNull(handlerProvider, "handlerProvider is required");
Assert.notNull(handshakeHandler, "handshakeHandler is required");
this.handshakeHandler = handshakeHandler;
this.handlerProvider = handlerProvider;
this.handshakeHandler = new DefaultHandshakeHandler();
}
@Override