Skip to content

Package: Session

Session

Coverage

1: /*
2: * Copyright (c) 2018, 2021 Oracle and/or its affiliates and others.
3: * All rights reserved.
4: *
5: * This program and the accompanying materials are made available under the
6: * terms of the Eclipse Public License v. 2.0, which is available at
7: * http://www.eclipse.org/legal/epl-2.0.
8: *
9: * This Source Code may also be made available under the following Secondary
10: * Licenses when the conditions for such availability set forth in the
11: * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
12: * version 2 with the GNU Classpath Exception, which is available at
13: * https://www.gnu.org/software/classpath/license.html.
14: *
15: * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
16: */
17:
18: package jakarta.websocket;
19:
20: import java.io.Closeable;
21: import java.io.IOException;
22: import java.net.URI;
23: import java.security.Principal;
24: import java.util.List;
25: import java.util.Map;
26: import java.util.Set;
27:
28: /**
29: * A Web Socket session represents a conversation between two web socket endpoints. As soon as the websocket handshake
30: * completes successfully, the web socket implementation provides the endpoint an open websocket session. The endpoint
31: * can then register interest in incoming messages that are part of this newly created session by providing a
32: * MessageHandler to the session, and can send messages to the other end of the conversation by means of the
33: * RemoteEndpoint object obtained from this session.
34: * <p>
35: * Once the session is closed, it is no longer valid for use by applications. Calling any of its methods (with the
36: * exception of the close() methods) once the session has been closed will result in an
37: * {@link java.lang.IllegalStateException} being thrown. Developers should retrieve any information from the session
38: * during the {@link Endpoint#onClose} method. Following the convention of {@link java.io.Closeable} calling the Session
39: * close() methods after the Session has been closed has no effect.
40: * <p>
41: * Session objects may be called by multiple threads. Implementations must ensure the integrity of the mutable
42: * properties of the session under such circumstances.
43: *
44: * @author dannycoward
45: */
46: public interface Session extends Closeable {
47:
48: /**
49: * Return the container that this session is part of.
50: *
51: * @return the container.
52: */
53: WebSocketContainer getContainer();
54:
55: /**
56: * Register to handle to incoming messages in this conversation. A maximum of one message handler per native
57: * websocket message type (text, binary, pong) may be added to each Session. I.e. a maximum of one message handler
58: * to handle incoming text messages a maximum of one message handler for handling incoming binary messages, and a
59: * maximum of one for handling incoming pong messages. For further details of which message handlers handle which of
60: * the native websocket message types please see {@link MessageHandler.Whole} and {@link MessageHandler.Partial}.
61: * Adding more than one of any one type will result in a runtime exception.
62: * <p>
63: * This method is not safe to use unless you are providing an anonymous class derived directly from
64: * {@link jakarta.websocket.MessageHandler.Whole} or {@link jakarta.websocket.MessageHandler.Partial}. In all other
65: * cases (Lambda Expressions, more complex inheritance or generic type arrangements), one of the following methods
66: * have to be used: {@link #addMessageHandler(Class, jakarta.websocket.MessageHandler.Whole)} or
67: * {@link #addMessageHandler(Class, jakarta.websocket.MessageHandler.Partial)}.
68: * <p>
69: * Once the container has identified a MessageHandler for a message, the MessageHandler is used for the entirety of
70: * the message irrespective of any subsequent changes to the MessageHandlers configured for the Session.
71: *
72: * @param handler the MessageHandler to be added.
73: * @throws IllegalStateException if there is already a MessageHandler registered for the same native websocket
74: * message type as this handler.
75: */
76: void addMessageHandler(MessageHandler handler) throws IllegalStateException;
77:
78: /**
79: * Register to handle to incoming messages in this conversation. A maximum of one message handler per native
80: * websocket message type (text, binary, pong) may be added to each Session. I.e. a maximum of one message handler
81: * to handle incoming text messages a maximum of one message handler for handling incoming binary messages, and a
82: * maximum of one for handling incoming pong messages. For further details of which message handlers handle which of
83: * the native websocket message types please see {@link MessageHandler.Whole} and {@link MessageHandler.Partial}.
84: * Adding more than one of any one type will result in a runtime exception.
85: * <p>
86: * Once the container has identified a MessageHandler for a message, the MessageHandler is used for the entirety of
87: * the message irrespective of any subsequent changes to the MessageHandlers configured for the Session.
88: *
89: * @param <T> type of message that the given handler is intended for.
90: * @param clazz type of the message processed by message handler to be registered.
91: * @param handler whole message handler to be added.
92: * @throws IllegalStateException if there is already a MessageHandler registered for the same native websocket
93: * message type as this handler.
94: * @since WebSocket 1.1
95: */
96: public <T> void addMessageHandler(Class<T> clazz, MessageHandler.Whole<T> handler);
97:
98: /**
99: * Register to handle to incoming messages in this conversation. A maximum of one message handler per native
100: * websocket message type (text, binary, pong) may be added to each Session. I.e. a maximum of one message handler
101: * to handle incoming text messages a maximum of one message handler for handling incoming binary messages, and a
102: * maximum of one for handling incoming pong messages. For further details of which message handlers handle which of
103: * the native websocket message types please see {@link MessageHandler.Whole} and {@link MessageHandler.Partial}.
104: * Adding more than one of any one type will result in a runtime exception.
105: * <p>
106: * Once the container has identified a MessageHandler for a message, the MessageHandler is used for the entirety of
107: * the message irrespective of any subsequent changes to the MessageHandlers configured for the Session.
108: *
109: * @param <T> type of message that the given handler is intended for.
110: * @param clazz type of the message processed by message handler to be registered.
111: * @param handler partial message handler to be added.
112: * @throws IllegalStateException if there is already a MessageHandler registered for the same native websocket
113: * message type as this handler.
114: * @since WebSocket 1.1
115: */
116: public <T> void addMessageHandler(Class<T> clazz, MessageHandler.Partial<T> handler);
117:
118: /**
119: * Return an unmodifiable copy of the set of MessageHandlers for this Session.
120: *
121: * @return the set of message handlers.
122: */
123: Set<MessageHandler> getMessageHandlers();
124:
125: /**
126: * Remove the given MessageHandler from the set belonging to this session. This method may block if the given
127: * handler is processing a message until it is no longer in use.
128: * <p>
129: * Once the container has identified a MessageHandler for a message, the MessageHandler is used for the entirety of
130: * the message irrespective of any subsequent changes to the MessageHandlers configured for the Session.
131: *
132: * @param handler the handler to be removed.
133: */
134: void removeMessageHandler(MessageHandler handler);
135:
136: /**
137: * Returns the version of the websocket protocol currently being used. This is taken as the value of the
138: * Sec-WebSocket-Version header used in the opening handshake. i.e. "13".
139: *
140: * @return the protocol version.
141: */
142: String getProtocolVersion();
143:
144: /**
145: * Return the sub protocol agreed during the websocket handshake for this conversation.
146: *
147: * @return the negotiated subprotocol, or the empty string if there isn't one.
148: */
149: String getNegotiatedSubprotocol();
150:
151: /**
152: * Return the list of extensions currently in use for this conversation.
153: *
154: * @return the negotiated extensions.
155: */
156: List<Extension> getNegotiatedExtensions();
157:
158: /**
159: * Return true if and only if the underlying socket is using a secure transport.
160: *
161: * @return whether its using a secure transport.
162: */
163: boolean isSecure();
164:
165: /**
166: * Return true if and only if the underlying socket is open.
167: *
168: * @return whether the session is active.
169: */
170: boolean isOpen();
171:
172: /**
173: * Return the number of milliseconds before this session will be closed by the container if it is inactive, i.e. no
174: * messages are either sent or received in that time. A value that is zero or negative indicates that this timeout
175: * will not be used.
176: *
177: * @return the timeout in milliseconds.
178: */
179: long getMaxIdleTimeout();
180:
181: /**
182: * Set the number of milliseconds before this session will be closed by the container if it is inactive, i.e. no
183: * messages are either sent or received in that time. A value that is zero or negative indicates that this timeout
184: * will not be used.
185: *
186: * @param milliseconds the number of milliseconds.
187: */
188: void setMaxIdleTimeout(long milliseconds);
189:
190: /**
191: * Sets the maximum length of incoming binary messages that this Session can buffer.
192: *
193: * @param length the maximum length.
194: */
195: void setMaxBinaryMessageBufferSize(int length);
196:
197: /**
198: * The maximum length of incoming binary messages that this Session can buffer. If the implementation receives a
199: * binary message that it cannot buffer because it is too large, it must close the session with a close code of
200: * {@link CloseReason.CloseCodes#TOO_BIG}.
201: *
202: * @return the maximum binary message size that can be buffered.
203: */
204: int getMaxBinaryMessageBufferSize();
205:
206: /**
207: * Sets the maximum length of incoming text messages that this Session can buffer.
208: *
209: * @param length the maximum length.
210: */
211: void setMaxTextMessageBufferSize(int length);
212:
213: /**
214: * The maximum length of incoming text messages that this Session can buffer. If the implementation receives a text
215: * message that it cannot buffer because it is too large, it must close the session with a close code of
216: * {@link CloseReason.CloseCodes#TOO_BIG}.
217: *
218: * @return the maximum text message size that can be buffered.
219: */
220: int getMaxTextMessageBufferSize();
221:
222: /**
223: * Return a reference a RemoteEndpoint object representing the peer of this conversation that is able to send
224: * messages asynchronously to the peer.
225: *
226: * @return the remote endpoint.
227: */
228: RemoteEndpoint.Async getAsyncRemote();
229:
230: /**
231: * Return a reference a RemoteEndpoint object representing the peer of this conversation that is able to send
232: * messages synchronously to the peer.
233: *
234: * @return the remote endpoint.
235: */
236: RemoteEndpoint.Basic getBasicRemote();
237:
238: /**
239: * Returns a string containing the unique identifier assigned to this session. The identifier is assigned by the web
240: * socket implementation and is implementation dependent.
241: *
242: * @return the unique identifier for this session instance.
243: */
244: String getId();
245:
246: /**
247: * Close the current conversation with a normal status code and no reason phrase.
248: *
249: * @throws IOException if there was a connection error closing the connection.
250: */
251: @Override
252: void close() throws IOException;
253:
254: /**
255: * Close the current conversation, giving a reason for the closure. The close call causes the implementation to
256: * attempt notify the client of the close as soon as it can. This may cause the sending of unsent messages
257: * immediately prior to the close notification. After the close notification has been sent the implementation
258: * notifies the endpoint's onClose method. Note the websocket specification defines the acceptable uses of status
259: * codes and reason phrases. If the application cannot determine a suitable close code to use for the closeReason,
260: * it is recommended to use {@link CloseReason.CloseCodes#NO_STATUS_CODE}.
261: *
262: * @param closeReason the reason for the closure.
263: * @throws IOException if there was a connection error closing the connection
264: */
265: void close(CloseReason closeReason) throws IOException;
266:
267: /**
268: * Return the complete URI under which this session was opened, from protocol to query string (if present). The URI
269: * should be identical to the complete URI used for the HTTP request that was upgraded to WebSocket apart from the
270: * protocol which should be changed to {@code ws} or {@code wss} as appropriate. It is the URI associated with the
271: * HTTP request that received the {@code 101 Switching Protocols} response that is used as the basis for this value
272: * - not an earlier, redirected request - if any.
273: *
274: * @return the request URI.
275: */
276: URI getRequestURI();
277:
278: /**
279: * Return the request parameters associated with the request this session was opened under. The request parameters
280: * will have been part of the HTTP upgrade request which is limited by RFC 6455 to only use the HTTP GET method.
281: * Therefore, the parameters in the returned Map will be a representation of the parameters contained in the query
282: * string.
283: *
284: * @return the unmodifiable map of the request parameters.
285: */
286: Map<String, List<String>> getRequestParameterMap();
287:
288: /**
289: * Return the query string associated with the request this session was opened under.
290: *
291: * @return the query string
292: */
293: String getQueryString();
294:
295: /**
296: * Return a map of the path parameter names and values used associated with the request this session was opened
297: * under.
298: *
299: * @return the unmodifiable map of path parameters. The key of the map is the parameter name, the values in the map
300: * are the parameter values.
301: */
302: Map<String, String> getPathParameters();
303:
304: /**
305: * While the session is open, this method returns a Map that the developer may use to store application specific
306: * information relating to this session instance. The developer may retrieve information from this Map at any time
307: * between the opening of the session and during the onClose() method. But outside that time, any information stored
308: * using this Map may no longer be kept by the container. Web socket applications running on distributed
309: * implementations of the web container should make any application specific objects stored here
310: * java.io.Serializable, or the object may not be recreated after a failover.
311: * <p>
312: * For server sessions, the initial contents of this Map must be a shallow copy of the user properties map returned
313: * from {@code jakarta.websocket.server.ServerEndpointConfig#getUserProperties()} at the point the
314: * {@code jakarta.websocket.server.ServerEndpointConfig.Configurator#modifyHandshake()}
315: * method exits.
316: * <p>
317: * For client sessions, the initial contents of this Map must be a shallow copy of the user properties map returned
318: * from {@link ClientEndpointConfig#getUserProperties()} for the {@link ClientEndpointConfig} passed to
319: * {@link WebSocketContainer#connectToServer(Class, ClientEndpointConfig, URI)} or
320: * {@link WebSocketContainer#connectToServer(Endpoint, ClientEndpointConfig, URI)}.
321: *
322: * @return an editable Map of application data.
323: */
324: Map<String, Object> getUserProperties();
325:
326: /**
327: * Return the authenticated user for this Session or {@code null} if no user is authenticated for this session.
328: *
329: * @return the user principal.
330: */
331: Principal getUserPrincipal();
332:
333: /**
334: * Return a copy of the Set of all the open web socket sessions that represent connections to the same endpoint to
335: * which this session represents a connection. The Set includes the session this method is called on. These sessions
336: * may not still be open at any point after the return of this method. For example, iterating over the set at a
337: * later time may yield one or more closed sessions. Developers should use session.isOpen() to check.
338: *
339: * @return the set of sessions, open at the time of return.
340: */
341: Set<Session> getOpenSessions();
342: }