Skip to content

Commit 646a611

Browse files
committed
WebSocket API: working WebSocket with Netty implementation
1 parent 5949740 commit 646a611

File tree

26 files changed

+851
-139
lines changed

26 files changed

+851
-139
lines changed

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

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,38 @@
44
import io.jooby.Jooby;
55

66
import java.nio.file.Paths;
7+
import java.util.concurrent.Executors;
8+
import java.util.concurrent.ScheduledExecutorService;
9+
import java.util.concurrent.TimeUnit;
710
import java.util.concurrent.atomic.AtomicInteger;
811

912
public class WebSocketApp extends Jooby {
1013
{
11-
assets("/", Paths.get(System.getProperty("user.dir"), "examples", "www", "websocket"));
14+
assets("/?*", Paths.get(System.getProperty("user.dir"), "examples", "www", "websocket"));
1215

16+
ScheduledExecutorService executor = Executors
17+
.newSingleThreadScheduledExecutor();
1318
ws("/ws", ctx -> {
1419
AtomicInteger counter = new AtomicInteger();
15-
// ws.onConnect(ctx -> {
16-
// System.out.println("connect: " + counter.incrementAndGet());
17-
// });
18-
// ws.onMessage((ctx, msg) -> {
19-
// System.out.println("msg: " + counter.incrementAndGet() + " => " + msg);
20-
// System.out.println(Thread.currentThread());
21-
// });
20+
ctx.onConnect(ws -> {
21+
executor.scheduleWithFixedDelay(() -> {
22+
ws.send("" + counter.incrementAndGet());
23+
}, 0, 3, TimeUnit.SECONDS);
24+
});
25+
ctx.onMessage((ws, msg) -> {
26+
System.out.println("msg: " + counter.incrementAndGet() + " => " + msg.value());
27+
System.out.println(Thread.currentThread());
28+
// ws.send("Got: " + msg.value());
29+
});
30+
ctx.onClose((ws, closeStatus) -> {
31+
System.out.println("Closed " + closeStatus);
32+
});
33+
2234
});
2335
}
2436

2537
public static void main(String[] args) {
2638
runApp(args, ExecutionMode.DEFAULT, WebSocketApp::new);
27-
// runApp(args, ExecutionMode.EVENT_LOOP, WebSocketApp::new);
39+
// runApp(args, ExecutionMode.EVENT_LOOP, WebSocketApp::new);
2840
}
2941
}

examples/www/websocket/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
<div>
1212
<input type="button" id="connectBtn" value="CONNECT" onclick="connect()"/>
1313
<input type="button" id="sendBtn" value="SEND" onclick="send()" disabled="true"/>
14+
<input type="button" id="closeBtn" value="CLOSE" onclick="closeSocket()" disabled="true"/>
1415
</div>
1516
<div id="output">
1617
<p>Output</p>

examples/www/websocket/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ var webSocket;
22
var output = document.getElementById("output");
33
var connectBtn = document.getElementById("connectBtn");
44
var sendBtn = document.getElementById("sendBtn");
5+
var closeBtn = document.getElementById("closeBtn");
56
var protocol = window.location.pathname === "/secure" ? "wss" : "ws";
67
var port = protocol === "wss" ? 8043 : 8080;
78
function connect() {
@@ -18,7 +19,7 @@ function connect() {
1819
updateOutput("Connected!");
1920
connectBtn.disabled = true;
2021
sendBtn.disabled = false;
21-
22+
closeBtn.disabled = false;
2223
};
2324

2425
webSocket.onmessage = function (event) {

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
*/
66
package io.jooby;
77

8+
import io.jooby.internal.ReadOnlyContext;
9+
import io.jooby.internal.WebSocketSender;
10+
811
import javax.annotation.Nonnull;
912
import javax.annotation.Nullable;
1013
import java.io.InputStream;
@@ -1057,4 +1060,16 @@ public interface Context extends Registry {
10571060
* @return This context.
10581061
*/
10591062
@Nonnull Context setResetHeadersOnError(boolean value);
1063+
1064+
/* **********************************************************************************************
1065+
* Factory methods
1066+
* **********************************************************************************************
1067+
*/
1068+
static @Nonnull Context readOnly(@Nonnull Context ctx) {
1069+
return new ReadOnlyContext(ctx);
1070+
}
1071+
1072+
static @Nonnull Context websocket(@Nonnull Context ctx, @Nonnull WebSocket ws) {
1073+
return new WebSocketSender(ctx, ws);
1074+
}
10601075
}

jooby/src/main/java/io/jooby/Route.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
*/
66
package io.jooby;
77

8-
import io.jooby.internal.ResponseStartedContext;
9-
108
import javax.annotation.Nonnull;
119
import javax.annotation.Nullable;
1210
import java.io.Serializable;
@@ -249,7 +247,7 @@ public interface Handler extends Serializable {
249247
return ctx -> {
250248
Object result = apply(ctx);
251249
if (ctx.isResponseStarted()) {
252-
Context fwd = new ResponseStartedContext(ctx);
250+
Context fwd = Context.readOnly(ctx);
253251
next.apply(fwd, null);
254252
return fwd;
255253
} else {
@@ -582,7 +580,6 @@ public Route(@Nonnull String method, @Nonnull String pattern, @Nonnull Handler h
582580
this.produces = new ArrayList<>();
583581
}
584582
produces.forEach(this.produces::add);
585-
before = before == null ? ACCEPT : ACCEPT.then(before);
586583
}
587584
return this;
588585
}
@@ -620,7 +617,6 @@ public Route(@Nonnull String method, @Nonnull String pattern, @Nonnull Handler h
620617
this.consumes = new ArrayList<>();
621618
}
622619
consumes.forEach(this.consumes::add);
623-
before = before == null ? SUPPORT_MEDIA_TYPE : SUPPORT_MEDIA_TYPE.then(before);
624620
}
625621
return this;
626622
}

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 final class StatusCode {
20+
public class StatusCode {
2121

2222
// 1xx Informational
2323

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
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;
78

89
import javax.annotation.Nonnull;
910
import javax.annotation.Nullable;
11+
import java.lang.reflect.Type;
1012
import java.time.Instant;
1113
import java.time.LocalDateTime;
1214
import java.time.ZoneOffset;

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

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

33
public interface WebSocket {
44
interface Handler {
5-
void apply(Context ctx);
5+
void apply(WebSocketContext ctx);
66
}
77

88
interface OnConnect {
99
void onConnect(WebSocket ws);
1010
}
1111

1212
interface OnMessage {
13-
void onMessage(WebSocket ws);
13+
void onMessage(WebSocket ws, WebSocketMessage message);
1414
}
1515

16-
void onConnect(OnConnect listener);
16+
interface OnClose {
17+
void onClose(WebSocket ws, WebSocketCloseStatus closeStatus);
18+
}
19+
20+
interface OnError {
21+
void onError(WebSocket ws, Throwable cause);
22+
}
23+
24+
Context getContext();
1725

18-
void onMessage(OnMessage listener);
26+
WebSocket send(String message);
1927

20-
void onError(WebSocket ws, Throwable cause, StatusCode statusCode);
28+
WebSocket send(byte[] bytes);
2129

22-
void onClose(WebSocket ws, StatusCode reason);
30+
WebSocket render(Object message);
2331
}

0 commit comments

Comments
 (0)