diff options
Diffstat (limited to 'simple/simple-http/src/main/java/org/simpleframework/http/socket/service/SessionDispatcher.java')
-rw-r--r-- | simple/simple-http/src/main/java/org/simpleframework/http/socket/service/SessionDispatcher.java | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/simple/simple-http/src/main/java/org/simpleframework/http/socket/service/SessionDispatcher.java b/simple/simple-http/src/main/java/org/simpleframework/http/socket/service/SessionDispatcher.java new file mode 100644 index 0000000..6543be0 --- /dev/null +++ b/simple/simple-http/src/main/java/org/simpleframework/http/socket/service/SessionDispatcher.java @@ -0,0 +1,111 @@ +/* + * SessionDispatcher.java February 2014 + * + * Copyright (C) 2014, Niall Gallagher <niallg@users.sf.net> + * + * 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.simpleframework.http.socket.service; + +import static org.simpleframework.http.socket.service.ServiceEvent.DISPATCH_SOCKET; +import static org.simpleframework.http.socket.service.ServiceEvent.ERROR; +import static org.simpleframework.http.socket.service.ServiceEvent.TERMINATE_SOCKET; + +import org.simpleframework.http.Request; +import org.simpleframework.http.Response; +import org.simpleframework.http.socket.Session; +import org.simpleframework.transport.Channel; +import org.simpleframework.transport.trace.Trace; + +/** + * The <code>SessionDispatcher</code> object is used to perform the + * opening handshake for a WebSocket session. Once the session has been + * established it is connected to a <code>Service</code> where frames + * can be sent and received. If for any reason the handshake fails + * this will terminated the connection with a HTTP 400 response. + * + * @author Niall Gallagher + */ +class SessionDispatcher { + + /** + * This is used to create the session for the WebSocket. + */ + private final SessionBuilder builder; + + /** + * This is used to select the service to dispatch to. + */ + private final Router router; + + /** + * Constructor for the <code>SessionDispatcher</code> object. The + * dispatcher created will dispatch WebSocket sessions to a service + * using the provided <code>Router</code> instance. + * + * @param builder this is used to build the WebSocket session + * @param router this is used to select the service + */ + public SessionDispatcher(SessionBuilder builder, Router router) { + this.builder = builder; + this.router = router; + } + + /** + * This method is used to create a dispatch a <code>Session</code> to + * a specific service selected by a router. If the session initiating + * handshake fails for any reason this will close the underlying TCP + * connection and send a HTTP 400 response back to the client. + * + * @param request this is the session initiating request + * @param response this is the session initiating response + */ + public void dispatch(Request request, Response response) { + Channel channel = request.getChannel(); + Trace trace = channel.getTrace(); + + try { + Service service = router.route(request, response); + Session session = builder.create(request, response); + + trace.trace(DISPATCH_SOCKET); + service.connect(session); + } catch(Exception cause) { + trace.trace(ERROR, cause); + terminate(request, response); + } + } + + /** + * This method is used to terminate the connection and commit the + * response. Terminating the session before it has been dispatched + * is done when there is a protocol or an unexpected I/O error with + * the underlying TCP channel. + * + * @param request this is the session initiating request + * @param response this is the session initiating response + */ + public void terminate(Request request, Response response) { + Channel channel = request.getChannel(); + Trace trace = channel.getTrace(); + + try { + response.close(); + channel.close(); + trace.trace(TERMINATE_SOCKET); + } catch(Exception cause) { + trace.trace(ERROR, cause); + } + } +} |