Early iteration of new API
This commit is contained in:
parent
ce9e7b7560
commit
8010c680e0
|
@ -18,8 +18,6 @@ package org.eclipse.jetty.websocket;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
|
||||
/**
|
||||
* WebSocket Interface.
|
||||
* <p>
|
||||
|
@ -27,50 +25,31 @@ import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
|||
* The Interface has several nested interfaces, for each type of message that may be received.
|
||||
*/
|
||||
public interface WebSocket
|
||||
{
|
||||
{
|
||||
/**
|
||||
* A Connection interface is passed to a WebSocket instance via the {@link WebSocket#onOpen(Connection)} to give the application access to the specifics of
|
||||
* the current connection. This includes methods for sending frames and messages as well as methods for interpreting the flags and opcodes of the
|
||||
* connection.
|
||||
* Called when a new websocket connection is accepted.
|
||||
* @param connection The Connection object to use to send messages.
|
||||
*/
|
||||
public interface Connection
|
||||
void onOpen(Connection connection);
|
||||
|
||||
/**
|
||||
* Called when an established websocket connection closes
|
||||
* @param closeCode
|
||||
* @param message
|
||||
*/
|
||||
void onClose(int closeCode, String message);
|
||||
|
||||
/**
|
||||
* A nested WebSocket interface for receiving text messages
|
||||
*/
|
||||
interface OnTextMessage extends WebSocket
|
||||
{
|
||||
/**
|
||||
* Close the connection with normal close code.
|
||||
* Called with a complete text message when all fragments have been received.
|
||||
* The maximum size of text message that may be aggregated from multiple frames is set with {@link Connection#setMaxTextMessageSize(int)}.
|
||||
* @param data The message
|
||||
*/
|
||||
void close();
|
||||
|
||||
/** Close the connection with specific closeCode and message.
|
||||
* @param closeCode The close code to send, or -1 for no close code
|
||||
* @param message The message to send or null for no message
|
||||
*/
|
||||
void close(int closeCode,String message);
|
||||
|
||||
/**
|
||||
* Enqueue a text message to be sent.
|
||||
* <p>
|
||||
* It is possible that the message might be split up and fragmented to satisfy
|
||||
* policies in place on the websocket.
|
||||
*
|
||||
* @param message the message text to send.
|
||||
* @throws IOException
|
||||
*/
|
||||
void enqueTextMessage(String message) throws IOException;
|
||||
|
||||
/**
|
||||
* Get the websocket policy in use for this connection.
|
||||
* @return connection specific websocket policy.
|
||||
*/
|
||||
WebSocketPolicy getPolicy();
|
||||
|
||||
/**
|
||||
* Get the active scheme. "ws" (websocket) or "wss" (websocket secure)
|
||||
*
|
||||
* @return the active protocol scheme
|
||||
*/
|
||||
String getProtocol();
|
||||
|
||||
boolean isOpen();
|
||||
void onMessage(String data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,13 +66,13 @@ public interface WebSocket
|
|||
*/
|
||||
void onMessage(byte[] data, int offset, int length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A nested WebSocket interface for receiving control messages
|
||||
*/
|
||||
interface OnControl extends WebSocket
|
||||
{
|
||||
/**
|
||||
/**
|
||||
* Called when a control message has been received.
|
||||
* @param controlCode
|
||||
* @param data
|
||||
|
@ -103,7 +82,7 @@ public interface WebSocket
|
|||
*/
|
||||
boolean onControl(byte controlCode,byte[] data, int offset, int length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A nested WebSocket interface for receiving any websocket frame
|
||||
*/
|
||||
|
@ -119,33 +98,176 @@ public interface WebSocket
|
|||
* @return true if this call has completely handled the frame and no further processing is needed (including aggregation and/or message delivery)
|
||||
*/
|
||||
boolean onFrame(byte flags,byte opcode,byte[] data, int offset, int length);
|
||||
|
||||
|
||||
void onHandshake(FrameConnection connection);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A nested WebSocket interface for receiving text messages
|
||||
* A Connection interface is passed to a WebSocket instance via the {@link WebSocket#onOpen(Connection)} to
|
||||
* give the application access to the specifics of the current connection. This includes methods
|
||||
* for sending frames and messages as well as methods for interpreting the flags and opcodes of the connection.
|
||||
*/
|
||||
interface OnTextMessage extends WebSocket
|
||||
public interface Connection
|
||||
{
|
||||
String getProtocol();
|
||||
void sendMessage(String data) throws IOException;
|
||||
void sendMessage(byte[] data, int offset, int length) throws IOException;
|
||||
|
||||
/**
|
||||
* Called with a complete text message when all fragments have been received.
|
||||
* The maximum size of text message that may be aggregated from multiple frames is set with {@link Connection#setMaxTextMessageSize(int)}.
|
||||
* @param data The message
|
||||
* @deprecated Use {@link #close()}
|
||||
*/
|
||||
void onMessage(String data);
|
||||
void disconnect();
|
||||
|
||||
/**
|
||||
* Close the connection with normal close code.
|
||||
*/
|
||||
void close();
|
||||
|
||||
/** Close the connection with specific closeCode and message.
|
||||
* @param closeCode The close code to send, or -1 for no close code
|
||||
* @param message The message to send or null for no message
|
||||
*/
|
||||
void close(int closeCode,String message);
|
||||
|
||||
boolean isOpen();
|
||||
|
||||
/**
|
||||
* @param ms The time in ms that the connection can be idle before closing
|
||||
*/
|
||||
void setMaxIdleTime(int ms);
|
||||
|
||||
/**
|
||||
* @param size size<0 No aggregation of frames to messages, >=0 max size of text frame aggregation buffer in characters
|
||||
*/
|
||||
void setMaxTextMessageSize(int size);
|
||||
|
||||
/**
|
||||
* @param size size<0 no aggregation of binary frames, >=0 size of binary frame aggregation buffer
|
||||
*/
|
||||
void setMaxBinaryMessageSize(int size);
|
||||
|
||||
/**
|
||||
* @return The time in ms that the connection can be idle before closing
|
||||
*/
|
||||
int getMaxIdleTime();
|
||||
|
||||
/**
|
||||
* Size in characters of the maximum text message to be received
|
||||
* @return size <0 No aggregation of frames to messages, >=0 max size of text frame aggregation buffer in characters
|
||||
*/
|
||||
int getMaxTextMessageSize();
|
||||
|
||||
/**
|
||||
* Size in bytes of the maximum binary message to be received
|
||||
* @return size <0 no aggregation of binary frames, >=0 size of binary frame aggregation buffer
|
||||
*/
|
||||
int getMaxBinaryMessageSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an established websocket connection closes
|
||||
* @param closeCode
|
||||
* @param message
|
||||
* Frame Level Connection
|
||||
* <p>The Connection interface at the level of sending/receiving frames rather than messages.
|
||||
* Also contains methods to decode/generate flags and opcodes without using constants, so that
|
||||
* code can be written to work with multiple drafts of the protocol.
|
||||
*
|
||||
*/
|
||||
void onClose(int closeCode, String message);
|
||||
public interface FrameConnection extends Connection
|
||||
{
|
||||
/**
|
||||
* @return The opcode of a binary message
|
||||
*/
|
||||
byte binaryOpcode();
|
||||
|
||||
/**
|
||||
* @return The opcode of a text message
|
||||
*/
|
||||
byte textOpcode();
|
||||
|
||||
/**
|
||||
* @return The opcode of a continuation frame
|
||||
*/
|
||||
byte continuationOpcode();
|
||||
|
||||
/**
|
||||
* @return Mask for the FIN bit.
|
||||
*/
|
||||
byte finMask();
|
||||
|
||||
/** Set if frames larger than the frame buffer are handled with local fragmentations
|
||||
* @param allowFragmentation
|
||||
*/
|
||||
void setAllowFrameFragmentation(boolean allowFragmentation);
|
||||
|
||||
/**
|
||||
* Called when a new websocket connection is accepted.
|
||||
* @param connection The Connection object to use to send messages.
|
||||
*/
|
||||
void onOpen(Connection connection);
|
||||
/**
|
||||
* @param flags The flags bytes of a frame
|
||||
* @return True of the flags indicate a final frame.
|
||||
*/
|
||||
boolean isMessageComplete(byte flags);
|
||||
|
||||
/**
|
||||
* @param opcode
|
||||
* @return True if the opcode is for a control frame
|
||||
*/
|
||||
boolean isControl(byte opcode);
|
||||
|
||||
/**
|
||||
* @param opcode
|
||||
* @return True if the opcode is for a text frame
|
||||
*/
|
||||
boolean isText(byte opcode);
|
||||
|
||||
/**
|
||||
* @param opcode
|
||||
* @return True if the opcode is for a binary frame
|
||||
*/
|
||||
boolean isBinary(byte opcode);
|
||||
|
||||
/**
|
||||
* @param opcode
|
||||
* @return True if the opcode is for a continuation frame
|
||||
*/
|
||||
boolean isContinuation(byte opcode);
|
||||
|
||||
/**
|
||||
* @param opcode
|
||||
* @return True if the opcode is a close control
|
||||
*/
|
||||
boolean isClose(byte opcode);
|
||||
|
||||
/**
|
||||
* @param opcode
|
||||
* @return True if the opcode is a ping control
|
||||
*/
|
||||
boolean isPing(byte opcode);
|
||||
|
||||
/**
|
||||
* @param opcode
|
||||
* @return True if the opcode is a pong control
|
||||
*/
|
||||
boolean isPong(byte opcode);
|
||||
|
||||
/**
|
||||
* @return True if frames larger than the frame buffer are fragmented.
|
||||
*/
|
||||
boolean isAllowFrameFragmentation();
|
||||
|
||||
/** Send a control frame
|
||||
* @param control
|
||||
* @param data
|
||||
* @param offset
|
||||
* @param length
|
||||
* @throws IOException
|
||||
*/
|
||||
void sendControl(byte control,byte[] data, int offset, int length) throws IOException;
|
||||
|
||||
/** Send an arbitrary frame
|
||||
* @param flags
|
||||
* @param opcode
|
||||
* @param data
|
||||
* @param offset
|
||||
* @param length
|
||||
* @throws IOException
|
||||
*/
|
||||
void sendFrame(byte flags,byte opcode,byte[] data, int offset, int length) throws IOException;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package org.eclipse.jetty.websocket.api;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Proposed interface for API (not yet settled)
|
||||
*/
|
||||
public interface ExtensionRef
|
||||
{
|
||||
String getName();
|
||||
|
||||
Map<String, String> getParameters();
|
||||
}
|
|
@ -1,76 +1,171 @@
|
|||
package org.eclipse.jetty.websocket.api;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.websocket.frames.BaseFrame;
|
||||
import org.eclipse.jetty.websocket.frames.BinaryFrame;
|
||||
import org.eclipse.jetty.websocket.frames.CloseFrame;
|
||||
import org.eclipse.jetty.websocket.frames.ControlFrame;
|
||||
import org.eclipse.jetty.websocket.frames.DataFrame;
|
||||
import org.eclipse.jetty.websocket.frames.PingFrame;
|
||||
import org.eclipse.jetty.websocket.frames.TextFrame;
|
||||
|
||||
|
||||
/**
|
||||
* Constants for WebSocket protocol as-defined in <a href="https://tools.ietf.org/html/rfc6455">RFC-6455</a>.
|
||||
* <p>
|
||||
* NOTE: Proposed interface for API (not yet settled)
|
||||
*/
|
||||
public interface WebSocket
|
||||
{
|
||||
/**
|
||||
* Server side interface (to be moved once API settles down)
|
||||
*/
|
||||
public static interface Accept
|
||||
{
|
||||
WebSocket acceptWebSocket(WebSocketHandshakeRequest request, WebSocketHandshakeResponse response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Advanced usage, for those interested in flags
|
||||
*/
|
||||
public static interface BinaryFrameListener
|
||||
{
|
||||
void onWebSocketBinary(BinaryFrame frame);
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic usage.
|
||||
*/
|
||||
public static interface BinaryListener
|
||||
{
|
||||
void onWebSocketBinary(byte buf[], int offset, int len);
|
||||
}
|
||||
|
||||
/**
|
||||
* NIO flavored basic usage.
|
||||
*/
|
||||
public static interface ByteBufferListener
|
||||
{
|
||||
void onWebSocketBinary(ByteBuffer... buffer);
|
||||
}
|
||||
|
||||
public static interface Connection
|
||||
{
|
||||
/**
|
||||
* Terminate connection, normally, without a reason.
|
||||
* <p>
|
||||
* Issues a CloseFrame via {@link #write(Object, Callback, BaseFrame...)}
|
||||
*
|
||||
* @TODO: determine contract for dealing with pending incoming frames.
|
||||
*/
|
||||
void close();
|
||||
|
||||
/**
|
||||
* Terminate connection, with status code.
|
||||
* <p>
|
||||
* Issues a CloseFrame via {@link #write(Object, Callback, BaseFrame...)}
|
||||
*
|
||||
* @param statusCode
|
||||
* the status code
|
||||
* @param reason
|
||||
* the (optional) reason. (can be null for no reason)
|
||||
* @TODO: determine contract for dealing with pending incoming frames.
|
||||
*/
|
||||
void close(int statusCode, String reason);
|
||||
|
||||
String getSubProtocol();
|
||||
|
||||
boolean isOpen();
|
||||
|
||||
/**
|
||||
* Basic usage, results in non-blocking call to {@link #write(Object, Callback, ByteBuffer...)}
|
||||
*/
|
||||
void sendBinary(byte[] data, int offset, int length) throws IOException;
|
||||
|
||||
/**
|
||||
* Basic usage, results in non-blocking call to {@link #write(Object, Callback, ByteBuffer...)}
|
||||
*/
|
||||
void sendBinary(ByteBuffer buffer) throws IOException;
|
||||
|
||||
/**
|
||||
* Basic usage, results in non-blocking call to {@link #write(Object, Callback, ByteBuffer...)}
|
||||
*/
|
||||
void sendBinary(ByteBuffer... buffers) throws IOException;
|
||||
|
||||
/**
|
||||
* Basic usage, results in non-blocking call to {@link #write(Object, Callback, String...)}
|
||||
*/
|
||||
void sendText(String message) throws IOException;
|
||||
|
||||
/**
|
||||
* Advanced usage, with callbacks, enters into outgoing queue
|
||||
*/
|
||||
<C> void write(C context, Callback<C> callback, BaseFrame... frames) throws IOException;
|
||||
|
||||
/**
|
||||
* Advanced usage, with callbacks, enters into outgoing queue
|
||||
*/
|
||||
<C> void write(C context, Callback<C> callback, ByteBuffer... buffers) throws IOException;
|
||||
|
||||
/**
|
||||
* Advanced usage, with callbacks, enters into outgoing queue
|
||||
*/
|
||||
<C> void write(C context, Callback<C> callback, String... messages) throws IOException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advanced usage, text frame access to flags as well
|
||||
*/
|
||||
public static interface TextFrameListener
|
||||
{
|
||||
void onWebSocketTextFrame(TextFrame frame);
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic usage
|
||||
*/
|
||||
public static interface TextListener
|
||||
{
|
||||
void onWebSocketText(String message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Per <a href="https://tools.ietf.org/html/rfc6455#section-1.3">RFC 6455, section 1.3</a> - Opening Handshake - this version is "13"
|
||||
*/
|
||||
public final static int VERSION = 13;
|
||||
|
||||
/*
|
||||
* Connection
|
||||
* - void terminateConnection();
|
||||
* - void terminateConnection(int statusCode);
|
||||
* - void terminateConnection(int statusCode, String reason);
|
||||
* - FutureCallback<Void> sendFrame(BaseFrame frame)
|
||||
* - FutureCallback<Void> sendText(String text)
|
||||
* - FutureCallback<Void> sendBinary(ByteBuffer payload)
|
||||
* - FutureCallback<Void> sendBinary(byte buf[], int offset, int len)
|
||||
*
|
||||
* @OnWebSocketHandshake
|
||||
* public void {methodname}(Connection conn)
|
||||
*
|
||||
* @OnWebSocketConnect
|
||||
* public void {methodname}(Connection conn)
|
||||
*
|
||||
* @OnWebSocketDisconnect
|
||||
* public void {methodname}(Connection conn)
|
||||
*
|
||||
* @OnWebSocketFrame(type=CloseFrame.class)
|
||||
* public void {methodname}(CloseFrame frame);
|
||||
*
|
||||
* @OnWebSocketText
|
||||
* public void {methodname}(String text);
|
||||
*
|
||||
* @OnWebSocketBinary
|
||||
* public void {methodname}(byte buf[], int offset, int length);
|
||||
* public void {methodname}(ByteBuffer buffer);
|
||||
*
|
||||
* @OnWebSocketClose
|
||||
* public void {methodnamne}(int statusCode, String reason);
|
||||
*/
|
||||
|
||||
void onBinaryFrame(BinaryFrame frame);
|
||||
|
||||
void onClose(int statusCode, String reason);
|
||||
void onCloseFrame(CloseFrame frame);
|
||||
|
||||
void onControlFrame(ControlFrame frame);
|
||||
void onDataFrame(DataFrame frame);
|
||||
void onHandshake(/* what params? */);
|
||||
void onConnect(WebSocket.Connection connection);
|
||||
|
||||
void onOpen();
|
||||
void onTextFrame(TextFrame frame);
|
||||
|
||||
void sendBinary(byte buf[]);
|
||||
void sendBinary(ByteBuffer buffer);
|
||||
|
||||
Future<Runnable> sendFrame(BaseFrame frame);
|
||||
void sendPong(PingFrame frame);
|
||||
void sendText(String message);
|
||||
/**
|
||||
* Annotation Ideas (Various WebSocket Events):
|
||||
*
|
||||
* <pre>
|
||||
* @OnWebSocketHandshake (server side only?)
|
||||
* public void {methodname}(WebSocket.Connection conn)
|
||||
*
|
||||
* @OnWebSocketConnect
|
||||
* public void {methodname}(WebSocket.Connection conn)
|
||||
*
|
||||
* @OnWebSocketDisconnect
|
||||
* public void {methodname}(WebSocket.Connection conn)
|
||||
*
|
||||
* @OnWebSocketFrame(type=CloseFrame.class)
|
||||
* public void {methodname}(CloseFrame frame);
|
||||
* public void {methodname}(WebSocket.Connection conn, CloseFrame frame);
|
||||
*
|
||||
* @OnWebSocketText
|
||||
* public void {methodname}(String text);
|
||||
* public void {methodname}(WebSocket.Connection conn, String text);
|
||||
*
|
||||
* @OnWebSocketBinary
|
||||
* public void {methodname}(byte buf[], int offset, int length);
|
||||
* public void {methodname}(WebSocket.Connection conn, byte buf[], int offset, int length);
|
||||
* public void {methodname}(ByteBuffer buffer);
|
||||
* public void {methodname}(WebSocket.Connection conn, ByteBuffer buffer);
|
||||
*
|
||||
* @OnWebSocketClose
|
||||
* public void {methodnamne}(int statusCode, String reason);
|
||||
* public void {methodnamne}(WebSocket.Connection conn, int statusCode, String reason);
|
||||
* </pre>
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package org.eclipse.jetty.websocket.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Proposed interface for API (not yet settled)
|
||||
*/
|
||||
public interface WebSocketHandshakeRequest
|
||||
{
|
||||
// get/set arbitrary Http Header Fields? (if so, then this should not use servlet-api)
|
||||
|
||||
String getEndpoint();
|
||||
|
||||
List<ExtensionRef> getExtensions();
|
||||
|
||||
String getHost();
|
||||
|
||||
String getOrigin();
|
||||
|
||||
String getWebSocketKey();
|
||||
|
||||
String[] getWebSocketProtocols();
|
||||
|
||||
int getWebSocketVersion();
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package org.eclipse.jetty.websocket.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Proposed interface for API (not yet settled)
|
||||
*/
|
||||
public interface WebSocketHandshakeResponse
|
||||
{
|
||||
String getWebSocketAccept();
|
||||
|
||||
boolean isUpgradeAccepted();
|
||||
|
||||
void setExtensions(List<ExtensionRef> refs);
|
||||
|
||||
void setUpgradeAccepted(boolean accept);
|
||||
}
|
Loading…
Reference in New Issue