Cleaning up the API after the discussion with Jesse

This commit is contained in:
Joakim Erdfelt 2012-06-26 16:35:23 -07:00
parent 4eeb433b44
commit 41094cb685
9 changed files with 346 additions and 163 deletions

View File

@ -0,0 +1,31 @@
package org.eclipse.jetty.websocket.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.nio.ByteBuffer;
import org.eclipse.jetty.websocket.api.WebSocketConnection;
/**
* Annotation for tagging methods to receive Binary message events.
* <p>
* Acceptable method patterns.<br>
* Note: <code><u>methodName</u></code> can be any name you want to use.
* <ol>
* <li><code>public void methodName(byte payload[], int offset, int length)</code></li>
* <li><code>public void methodName({@link ByteBuffer} payload)</code></li>
* <li><code>public void methodName({@link WebSocketConnection} conn, byte payload[], int offset, int length)</code></li>
* <li><code>public void methodName({@link WebSocketConnection} conn, {@link ByteBuffer} payload)</code></li>
* </ol>
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value =
{ ElementType.METHOD })
public @interface OnWebSocketBinary
{
/* no config */
}

View File

@ -0,0 +1,28 @@
package org.eclipse.jetty.websocket.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.eclipse.jetty.websocket.api.WebSocketConnection;
/**
* Annotation for tagging methods to receive connection close events.
* <p>
* Acceptable method patterns.<br>
* Note: <code>methodName</code> can be any name you want to use.
* <ol>
* <li><code>public void methodName(int statusCode, String reason)</code></li>
* <li><code>public void methodName({@link WebSocketConnection} conn, int statusCode, String reason)</code></li>
* </ol>
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value =
{ ElementType.METHOD })
public @interface OnWebSocketClose
{
/* no config */
}

View File

@ -0,0 +1,27 @@
package org.eclipse.jetty.websocket.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.eclipse.jetty.websocket.api.WebSocketConnection;
/**
* Annotation for tagging methods to receive connection open events.
* <p>
* Only 1 acceptable method pattern for this annotation.<br>
* Note: <code>methodName</code> can be any name you want to use.
* <ol>
* <li><code>public void methodName({@link WebSocketConnection} conn)</code></li>
* </ol>
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value =
{ ElementType.METHOD })
public @interface OnWebSocketConnect
{
/* no config */
}

View File

@ -0,0 +1,45 @@
package org.eclipse.jetty.websocket.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.eclipse.jetty.websocket.api.WebSocketConnection;
import org.eclipse.jetty.websocket.frames.BaseFrame;
/**
* (ADVANCED) Annotation for tagging methods to receive frame events.
* <p>
* Note: any frame derived from {@link BaseFrame} is acceptable to use as the last parameter here.
* <p>
* Acceptable method patterns.<br>
* Note: <code>methodName</code> can be any name you want to use.
* <ol>
* <li><code>public void methodName({@link BaseFrame} frame)</code></li>
* <li><code>public void methodName(BinaryFrame frame)</code></li>
* <li><code>public void methodName(CloseFrame frame)</code></li>
* <li><code>public void methodName(ControlFrame frame)</code></li>
* <li><code>public void methodName(DataFrame frame)</code></li>
* <li><code>public void methodName(PingFrame frame)</code></li>
* <li><code>public void methodName(PongFrame frame)</code></li>
* <li><code>public void methodName(TextFrame frame)</code></li>
* <li><code>public void methodName({@link WebSocketConnection} conn, {@link BaseFrame} frame)</code></li>
* <li><code>public void methodName({@link WebSocketConnection} conn, BinaryFrame frame)</code></li>
* <li><code>public void methodName({@link WebSocketConnection} conn, CloseFrame frame)</code></li>
* <li><code>public void methodName({@link WebSocketConnection} conn, ControlFrame frame)</code></li>
* <li><code>public void methodName({@link WebSocketConnection} conn, DataFrame frame)</code></li>
* <li><code>public void methodName({@link WebSocketConnection} conn, PingFrame frame)</code></li>
* <li><code>public void methodName({@link WebSocketConnection} conn, PongFrame frame)</code></li>
* <li><code>public void methodName({@link WebSocketConnection} conn, TextFrame frame)</code></li>
* </ol>
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value =
{ ElementType.METHOD })
public @interface OnWebSocketFrame
{
/* no config */
}

View File

@ -0,0 +1,28 @@
package org.eclipse.jetty.websocket.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.eclipse.jetty.websocket.api.WebSocketConnection;
/**
* Annotation for tagging methods to receive Text message events.
* <p>
* Acceptable method patterns.<br>
* Note: <code>methodName</code> can be any name you want to use.
* <ol>
* <li><code>public void methodName(String text)</code></li>
* <li><code>public void methodName({@link WebSocketConnection} conn, String text)</code></li>
* </ol>
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value =
{ ElementType.METHOD })
public @interface OnWebSocketText
{
/* no config */
}

View File

@ -0,0 +1,23 @@
package org.eclipse.jetty.websocket.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Tags a POJO as being a WebSocket class.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value =
{ ElementType.TYPE })
public @interface WebSocket
{
int maxBinarySize() default 8192;
int maxBufferSize() default 8192;
int maxTextSize() default 8192;
}

View File

@ -1,163 +0,0 @@
package org.eclipse.jetty.websocket.api;
import java.io.IOException;
import java.nio.ByteBuffer;
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.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
{
/**
* 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;
void onClose(int statusCode, String reason);
void onConnect(WebSocket.Connection connection);
/**
* 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>
*/
}

View File

@ -0,0 +1,104 @@
package org.eclipse.jetty.websocket.api;
import java.io.IOException;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.Callback;
/**
* Connection interface for WebSocket protocol <a href="https://tools.ietf.org/html/rfc6455">RFC-6455</a>.
*/
public interface WebSocketConnection
{
/**
* Terminate connection, {@link StatusCode#NORMAL}, without a reason.
* <p>
* Basic usage: results in an non-blocking async write, then connection close.
*/
void close();
/**
* Terminate connection, with status code.
* <p>
* Advanced usage: results in an non-blocking async write, then connection close.
*
* @param statusCode
* the status code
* @param reason
* the (optional) reason. (can be null for no reason)
* @see StatusCode
*/
void close(int statusCode, String reason);
/**
* Access the (now read-only) {@link WebSocketPolicy} in use for this connection.
*
* @return the policy in use
*/
WebSocketPolicy getPolicy();
/**
* Get the remote Address in use for this connection.
*
* @return the remote address if available. (situations like mux extension and proxying makes this information unreliable)
*/
InetAddress getRemoteAddress();
/**
* Get the SubProtocol in use for this connection.
*
* @return the negotiated sub protocol name in use for this connection.
*/
String getSubProtocol();
/**
* Simple test to see if connection is open (and not closed)
*
* @return true if connection still open
*/
boolean isOpen();
/**
* Send a binary message.
* <p>
* Basic usage, results in an non-blocking async write.
*/
void write(byte[] data, int offset, int length) throws IOException;
/**
* Send a series of binary messages.
* <p>
* Note: each buffer results in its own binary message frame.
* <p>
* Basic usage, results in a series of non-blocking async writes.
*/
void write(ByteBuffer... buffers) throws IOException;
/**
* Send a series of binary messages.
* <p>
* Note: each buffer results in its own binary message frame.
* <p>
* Advanced usage, with callbacks, allows for concurrent NIO style results of the entire write operation. (Callback is only called once at the end of
* processing all of the buffers)
*/
<C> void write(C context, Callback<C> callback, ByteBuffer... buffers) throws IOException;
/**
* Send a series of text messages.
* <p>
* Note: each messages results in its own text message frame.
* <p>
* Advanced usage, with callbacks, allows for concurrent NIO style results of the entire write operation. (Callback is only called once at the end of
* processing all of the buffers)
*/
<C> void write(C context, Callback<C> callback, String... messages) throws IOException;
/**
* Send a text message.
* <p>
* Basic usage, results in an non-blocking async write.
*/
void write(String message) throws IOException;
}

View File

@ -0,0 +1,60 @@
package org.eclipse.jetty.websocket.api;
/**
* Basic WebSocket Listener interface for incoming WebSocket events.
*/
public interface WebSocketListener
{
/**
* A WebSocket binary frame has been received.
*
* @param payload the raw payload array received
* @param offset the offset in the payload array where the data starts
* @param len the length of bytes in the payload
*/
void onWebSocketBinary(byte payload[], int offset, int len);
/**
* A Close Event was received.
* <p>
* The underlying {@link WebSocketConnection} will be considered closed at this point.
*
* @param statusCode
* the close status code. (See {@link StatusCode})
* @param reason
* the optional reason for the close.
*/
void onWebSocketClose(int statusCode, String reason);
/**
* A WebSocketConnection has connected successfully and is ready to be used.
* <p>
* Note: It is a good idea to track this connection as a field in your object so that you can write messages back.
*
* @param connection
* the connection to use to send messages on.
*/
void onWebSocketConnect(WebSocketConnection connection);
/**
* A WebSocket exception has occurred.
* <p>
* Usually this occurs from bad / malformed incoming packets. (example: bad UTF8 data, frames that are too big, violations of the spec)
* <p>
* This will result in the {@link WebSocketConnection} being closed by the implementing side.
* <p>
* Note: you will receive no {@link #onWebSocketClose(int, String)} as this condition results in the API calling
* {@link WebSocketConnection#close(int, String)} for you.
*
* @param error
* the error that occurred.
*/
void onWebSocketException(WebSocketException error);
/**
* A WebSocket Text frame was received.
*
* @param message
*/
void onWebSocketText(String message);
}