Skip to content

Commit ec9f4c5

Browse files
committed
WebSocket API: document public API
1 parent 55d3923 commit ec9f4c5

File tree

11 files changed

+221
-27
lines changed

11 files changed

+221
-27
lines changed

examples/src/main/java/examples/WebSocketApp.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import io.jooby.ExecutionMode;
44
import io.jooby.Jooby;
5+
import io.jooby.WebSocketCloseStatus;
56

67
import java.nio.file.Paths;
78
import java.util.concurrent.Executors;
@@ -16,6 +17,7 @@ public class WebSocketApp extends Jooby {
1617
ws("/ws", (ctx, initializer) -> {
1718
initializer.onConnect(ws -> {
1819
ws.send("Welcome");
20+
ws.close();
1921
});
2022
initializer.onMessage((ws, msg) -> {
2123
ws.send("Got: " + msg.value(), true);

examples/www/websocket/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ function connect() {
2727
};
2828

2929
webSocket.onclose = function (event) {
30-
updateOutput("Connection Closed");
30+
console.log(event)
31+
updateOutput("Connection Closed: " + event.code + "(" + event.reason + ")");
3132
connectBtn.disabled = false;
3233
sendBtn.disabled = true;
3334
};

jooby/src/main/java/io/jooby/Context.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,10 +1065,32 @@ public interface Context extends Registry {
10651065
* Factory methods
10661066
* **********************************************************************************************
10671067
*/
1068+
1069+
/**
1070+
* Wrap a HTTP context and make read only. Attempt to modify the HTTP response resulted in
1071+
* exception.
1072+
*
1073+
* @param ctx Originating context.
1074+
* @return Read only context.
1075+
*/
10681076
static @Nonnull Context readOnly(@Nonnull Context ctx) {
10691077
return new ReadOnlyContext(ctx);
10701078
}
10711079

1080+
/**
1081+
* Wrap a HTTP context and make it WebSocket friendly. Attempt to modify the HTTP response
1082+
* is completely ignored, except for {@link #send(byte[])} and {@link #send(String)} which
1083+
* are delegated to the given web socket.
1084+
*
1085+
* This context is necessary for creating a bridge between {@link MessageEncoder}
1086+
* and {@link WebSocket}.
1087+
*
1088+
* This method is part of Public API, but direct usage is discourage.
1089+
*
1090+
* @param ctx Originating context.
1091+
* @param ws WebSocket.
1092+
* @return Read only context.
1093+
*/
10721094
static @Nonnull Context websocket(@Nonnull Context ctx, @Nonnull WebSocket ws) {
10731095
return new WebSocketSender(ctx, ws);
10741096
}

jooby/src/main/java/io/jooby/Jooby.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ public <T> Jooby mvc(@Nonnull Class<T> router, @Nonnull Provider<T> provider) {
292292
}
293293
}
294294

295-
public Route ws(String pattern, WebSocket.Initializer handler) {
295+
@Nonnull @Override public Route ws(@Nonnull String pattern, @Nonnull WebSocket.Initializer handler) {
296296
return router.ws(pattern, handler);
297297
}
298298

jooby/src/main/java/io/jooby/StatusCode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* @see <a href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes">List of HTTP status codes -
1818
* Wikipedia</a>
1919
*/
20-
public class StatusCode {
20+
public final class StatusCode {
2121

2222
// 1xx Informational
2323

jooby/src/main/java/io/jooby/Value.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@
44
import io.jooby.internal.HashValue;
55
import io.jooby.internal.MissingValue;
66
import io.jooby.internal.SingleValue;
7-
import io.jooby.internal.reflect.$Types;
87

98
import javax.annotation.Nonnull;
109
import javax.annotation.Nullable;
11-
import java.lang.reflect.Type;
1210
import java.time.Instant;
1311
import java.time.LocalDateTime;
1412
import java.time.ZoneOffset;

jooby/src/main/java/io/jooby/WebSocket.java

Lines changed: 103 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
*
2929
* }</pre>
3030
*
31+
* NOTE: Websocket API ONLY handles text messages (not binary message).
32+
*
3133
* @author edgar
3234
* @since 2.2.0
3335
*/
@@ -72,15 +74,43 @@ interface OnMessage {
7274
void onMessage(@Nonnull WebSocket ws, @Nonnull WebSocketMessage message);
7375
}
7476

77+
/**
78+
* On close callback. Generated when client close the connection or when explicit calls to
79+
* {@link #close(WebSocketCloseStatus)} or {@link #disconnect()}.
80+
*/
7581
interface OnClose {
76-
void onClose(WebSocket ws, WebSocketCloseStatus closeStatus);
82+
/**
83+
* Generated when client close the connection or when explicit calls to
84+
* {@link #close(WebSocketCloseStatus)} or {@link #disconnect()}.
85+
*
86+
* @param ws WebSocket.
87+
* @param closeStatus Close status.
88+
*/
89+
void onClose(@Nonnull WebSocket ws, @Nonnull WebSocketCloseStatus closeStatus);
7790
}
7891

92+
/**
93+
* On error callback. Generated when unexpected error occurs.
94+
*/
7995
interface OnError {
80-
void onError(WebSocket ws, Throwable cause);
96+
/**
97+
* Error callback, let you listen for exception. Websocket might or might not be open.
98+
*
99+
* @param ws Websocket.
100+
* @param cause Cause.
101+
*/
102+
void onError(@Nonnull WebSocket ws, @Nonnull Throwable cause);
81103
}
82104

83-
Context getContext();
105+
/**
106+
* Originating HTTP context. Please note this is a read-only context, so you are not allowed
107+
* to modify or produces a response from it.
108+
*
109+
* The context let give you access to originating request (then one that was upgrade it).
110+
*
111+
* @return Read-only originating HTTP request.
112+
*/
113+
@Nonnull Context getContext();
84114

85115
/**
86116
* Context attributes (a.k.a request attributes).
@@ -115,22 +145,84 @@ interface OnError {
115145
return this;
116146
}
117147

118-
default WebSocket send(String message) {
148+
/**
149+
* Send a text message to client.
150+
*
151+
* @param message Text Message.
152+
* @return This websocket.
153+
*/
154+
default @Nonnull WebSocket send(@Nonnull String message) {
119155
return send(message, false);
120156
}
121157

122-
WebSocket send(String message, boolean broadcast);
158+
/**
159+
* Send a text message to current client (broadcast = false) or to ALL connected clients under the
160+
* websocket path (broadcast = true).
161+
*
162+
* @param message Text Message.
163+
* @param broadcast True to send to all connected clients.
164+
* @return This websocket.
165+
*/
166+
@Nonnull WebSocket send(@Nonnull String message, boolean broadcast);
123167

124-
default WebSocket send(byte[] bytes) {
125-
return send(bytes, false);
168+
/**
169+
* Send a text message to client.
170+
*
171+
* @param message Text Message.
172+
* @return This websocket.
173+
*/
174+
default @Nonnull WebSocket send(@Nonnull byte[] message) {
175+
return send(message, false);
126176
}
127177

128-
WebSocket send(byte[] bytes, boolean broadcast);
178+
/**
179+
* Send a text message to current client (broadcast = false) or to ALL connected clients under the
180+
* websocket path (broadcast = true).
181+
*
182+
* @param message Text Message.
183+
* @param broadcast True to send to all connected clients.
184+
* @return This websocket.
185+
*/
186+
@Nonnull WebSocket send(@Nonnull byte[] message, boolean broadcast);
129187

130-
default WebSocket render(Object message) {
131-
return render(message, false);
188+
/**
189+
* Encode a value and send a text message to client.
190+
*
191+
* @param value Value to send.
192+
* @return This websocket.
193+
*/
194+
default @Nonnull WebSocket render(@Nonnull Object value) {
195+
return render(value, false);
132196
}
133197

134-
WebSocket render(Object message, boolean broadcast);
198+
/**
199+
* Encode a value and send a text message to current client (broadcast = false) or to ALL
200+
* connected clients under the websocket path (broadcast = true).
201+
*
202+
* @param value Value to send.
203+
* @param broadcast True to send to all connected clients.
204+
* @return This websocket.
205+
*/
206+
@Nonnull WebSocket render(@Nonnull Object value, boolean broadcast);
207+
208+
/**
209+
* Close the web socket and send a {@link WebSocketCloseStatus#NORMAL} code to client.
210+
*
211+
* This method fires a {@link OnClose#onClose(WebSocket, WebSocketCloseStatus)} callback.
212+
*
213+
* @return This websocket.
214+
*/
215+
default @Nonnull WebSocket close() {
216+
return close(WebSocketCloseStatus.NORMAL);
217+
}
135218

219+
/**
220+
* Close the web socket and send a close status code to client.
221+
*
222+
* This method fires a {@link OnClose#onClose(WebSocket, WebSocketCloseStatus)} callback.
223+
*
224+
* @param closeStatus Close status.
225+
* @return This websocket.
226+
*/
227+
@Nonnull WebSocket close(@Nonnull WebSocketCloseStatus closeStatus);
136228
}

jooby/src/main/java/io/jooby/WebSocketCloseStatus.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
package io.jooby;
22

3+
import javax.annotation.Nonnull;
4+
import javax.annotation.Nullable;
35
import java.util.Optional;
46

7+
/**
8+
* Collection of websocket close status.
9+
*
10+
* @author edgar
11+
* @since 2.2.0
12+
*/
513
public class WebSocketCloseStatus {
614

715
/**
@@ -181,19 +189,41 @@ public class WebSocketCloseStatus {
181189

182190
private String reason;
183191

184-
public WebSocketCloseStatus(int code, String reason) {
192+
/**
193+
* Creates a new websocket close status.
194+
*
195+
* @param code Status code.
196+
* @param reason Reason.
197+
*/
198+
public WebSocketCloseStatus(int code, @Nonnull String reason) {
185199
this.code = code;
186200
this.reason = reason;
187201
}
188202

203+
/**
204+
* Status code.
205+
*
206+
* @return Status code.
207+
*/
189208
public int getCode() {
190209
return code;
191210
}
192211

193-
public String getReason() {
212+
/**
213+
* Reason or <code>null</code>.
214+
*
215+
* @return Reason or <code>null</code>.
216+
*/
217+
public @Nullable String getReason() {
194218
return reason;
195219
}
196220

221+
/**
222+
* Map the status code to one of the existing web socket status.
223+
*
224+
* @param code Status code.
225+
* @return Web socket status or empty.
226+
*/
197227
public static Optional<WebSocketCloseStatus> valueOf(int code) {
198228
switch (code) {
199229
case -1:
Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,44 @@
11
package io.jooby;
22

3+
import javax.annotation.Nonnull;
4+
5+
/**
6+
* Websocket configurer. Allow to register callbacks for websocket.
7+
*
8+
* @author edgar
9+
* @since 2.2.0
10+
*/
311
public interface WebSocketConfigurer {
412

5-
WebSocketConfigurer onConnect(WebSocket.OnConnect callback);
13+
/**
14+
* Register an <code>onConnect</code> callback.
15+
*
16+
* @param callback Callback.
17+
* @return This configurer.
18+
*/
19+
@Nonnull WebSocketConfigurer onConnect(@Nonnull WebSocket.OnConnect callback);
620

7-
WebSocketConfigurer onMessage(WebSocket.OnMessage callback);
21+
/**
22+
* Register an <code>onMessage</code> callback.
23+
*
24+
* @param callback Callback.
25+
* @return This configurer.
26+
*/
27+
@Nonnull WebSocketConfigurer onMessage(@Nonnull WebSocket.OnMessage callback);
828

9-
WebSocketConfigurer onError(WebSocket.OnError callback);
29+
/**
30+
* Register an <code>onError</code> callback.
31+
*
32+
* @param callback Callback.
33+
* @return This configurer.
34+
*/
35+
@Nonnull WebSocketConfigurer onError(@Nonnull WebSocket.OnError callback);
1036

11-
WebSocketConfigurer onClose(WebSocket.OnClose callback);
37+
/**
38+
* Register an <code>onClose</code> callback.
39+
*
40+
* @param callback Callback.
41+
* @return This configurer.
42+
*/
43+
@Nonnull WebSocketConfigurer onClose(@Nonnull WebSocket.OnClose callback);
1244
}

jooby/src/main/java/io/jooby/WebSocketMessage.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
import javax.annotation.Nonnull;
66
import java.lang.reflect.Type;
77

8+
/**
9+
* Websocket message generated from a {@link WebSocket.OnMessage} callback. Message is a subclass.
10+
*
11+
* @author edgar
12+
* @since 2.2.0
13+
*/
814
public interface WebSocketMessage extends Value {
915
/**
1016
* Convert this value to the given type. Support values are single-value, array-value and
@@ -16,7 +22,14 @@ public interface WebSocketMessage extends Value {
1622
*/
1723
@Nonnull <T> T to(@Nonnull Type type);
1824

19-
static WebSocketMessage create(Context ctx, byte[] bytes) {
25+
/**
26+
* Creates a websocket message.
27+
*
28+
* @param ctx HTTP context.
29+
* @param bytes Text message as byte array.
30+
* @return A websocket message.
31+
*/
32+
static @Nonnull WebSocketMessage create(@Nonnull Context ctx, @Nonnull byte[] bytes) {
2033
return new WebSocketMessageImpl(ctx, bytes);
2134
}
2235
}

0 commit comments

Comments
 (0)