Skip to content

Commit e974c8b

Browse files
committed
Merge pull request vert-x#3 from InfoSec812/realtime-chat-example
Added realtime chat verticle example
2 parents 35a405a + 2cd9c77 commit e974c8b

File tree

4 files changed

+157
-2
lines changed

4 files changed

+157
-2
lines changed

apex-examples/README.adoc

+19
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,25 @@ timer that fires every second and sends a message to the `news-feed` address.
120120

121121
When you get the index page in your browser you should see it update every second as it receives a message.
122122

123+
== Real-time - chat service
124+
125+
This example demonstrates 2-way communication between the client and the server using the event bus bridge
126+
and web sockets.
127+
128+
The link:src/main/java/io/vertx/example/apex/realtime/ChatVerticle.java[Java real-time chat example]
129+
130+
The link:src/main/java/io/vertx/example/apex/realtime/webroot/chat.html[chat.html] file
131+
bootstraps the vertxbus.js bridge from the client and uses jQuery to handle manipulating
132+
the DOM and registering event handlers.
133+
134+
When you load the index page in a browser, you should see a div for chat messages and
135+
an input field where you can enter your own messages. Typing in the input field and
136+
pressing ENTER will cause the input to be sent via the event bus to the server. The server
137+
will accept the message, prepend it with a timestamp and publish back to all registered
138+
listeners (e.g. All connected clients). Take note of the addInboundPermitted and addOutboundPermitted
139+
settings on the BridgeOptions object to be sure that you authorize the correct messages
140+
to traverse the event bus bridge in the appropriate direction.
141+
123142
== Auth example
124143

125144
This example shows a basic static web-site that contains both public pages and pages that are only accessible to
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package io.vertx.example.apex.realtime;
2+
3+
import io.vertx.core.AbstractVerticle;
4+
import io.vertx.core.eventbus.EventBus;
5+
import io.vertx.example.util.Runner;
6+
import io.vertx.ext.apex.Router;
7+
import io.vertx.ext.apex.handler.StaticHandler;
8+
import io.vertx.ext.apex.handler.sockjs.BridgeOptions;
9+
import io.vertx.ext.apex.handler.sockjs.PermittedOptions;
10+
import io.vertx.ext.apex.handler.sockjs.SockJSHandler;
11+
import java.text.DateFormat;
12+
import java.time.Instant;
13+
import java.util.Date;
14+
15+
/**
16+
* A {@link io.vertx.core.Verticle} which implements a simple, realtime,
17+
* multiuser chat. Anyone can connect to the chat application on port
18+
* 8000 and type messages. The messages will be rebroadcast to all
19+
* connected users via the @{link EventBus} Websocket bridge.
20+
*
21+
* @author <a href="https://github.com/InfoSec812">Deven Phillips</a>
22+
*/
23+
public class Chat extends AbstractVerticle {
24+
// Convenience method so you can run it in your IDE
25+
public static void main(String[] args) {
26+
Runner.runExample(Chat.class);
27+
}
28+
29+
@Override
30+
public void start() throws Exception {
31+
32+
Router router = Router.router(vertx);
33+
34+
final EventBus eb = vertx.eventBus();
35+
36+
// Register to listen for messages coming IN to the server
37+
eb.consumer("chat.to.server").handler(message -> {
38+
// Create a timestamp string
39+
String timestamp = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM).format(Date.from(Instant.now()));
40+
// Send the message back out to all clients with the timestamp prepended.
41+
eb.publish("chat.to.client", timestamp+": "+message.body());
42+
});
43+
44+
// Allow events for the designated addresses in/out of the event bus bridge
45+
BridgeOptions opts = new BridgeOptions()
46+
.addInboundPermitted(new PermittedOptions().setAddress("chat.to.server"))
47+
.addOutboundPermitted(new PermittedOptions().setAddress("chat.to.client"));
48+
49+
// Create the event bus bridge and add it to the router.
50+
SockJSHandler ebHandler = SockJSHandler.create(vertx).bridge(opts);
51+
router.route("/eventbus/*").handler(ebHandler);
52+
53+
// Create a router endpoint for the static content.
54+
router.route().handler(StaticHandler.create("webroot").setIndexPage("chat.html"));
55+
56+
// Start the web server and tell it to use the router to handle requests.
57+
vertx.createHttpServer().requestHandler(router::accept).listen(8000);
58+
}
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<!--
2+
#%L
3+
distributed-chat-service
4+
%%
5+
Copyright (C) 2015 Zanclus Consulting
6+
%%
7+
Licensed under the Apache License, Version 2.0 (the "License");
8+
you may not use this file except in compliance with the License.
9+
You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
#L%
19+
-->
20+
<html>
21+
<head>
22+
<title>Distributed Chat Service</title>
23+
<meta charset="UTF-8">
24+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
25+
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
26+
<script src="//cdn.jsdelivr.net/sockjs/0.3.4/sockjs.min.js"></script>
27+
<script src="vertxbus.js"></script>
28+
<style>
29+
.inset {
30+
box-shadow:inset 0 0 4px #000000;
31+
-moz-box-shadow:inset 0 0 4px #000000;
32+
-webkit-box-shadow:inset 0 0 4px #000000;
33+
width: 400px;
34+
border-width: 4px;
35+
padding: 5px;
36+
}
37+
input.inset {
38+
height: 40px;
39+
}
40+
div.inset {
41+
height: 500px;
42+
white-space: pre-wrap
43+
}
44+
</style>
45+
</head>
46+
<body>
47+
<script>
48+
var eb = new vertx.EventBus("/eventbus/");
49+
eb.onopen = function() {
50+
eb.registerHandler("chat.to.client", function(msg) {
51+
$('#chat').append(msg+"\n");
52+
});
53+
};
54+
55+
function send(event) {
56+
if (event.keyCode==13 || event.which == 13) {
57+
var message = $('#input').val();
58+
if (message.length>0) {
59+
console.log($('#input'));
60+
eb.publish("chat.to.server", message);
61+
$('#input').val("");
62+
}
63+
}
64+
}
65+
</script>
66+
<div id="chat" class="inset"></div>
67+
<input id="input" type="text" onkeydown="send(event)" class="inset">
68+
</body>
69+
</html>

apex-examples/src/main/java/io/vertx/example/util/Runner.java

+10-2
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,13 @@ public static void main(String[] args) {
4141
}
4242

4343
static class JSRealtimeRunner {
44+
public static void main(String[] args) { Runner.runJSExample("io/vertx/example/apex/realtime/server.js"); }
45+
}
46+
47+
static class JSRealtimeChatRunner {
4448
public static void main(String[] args) {
45-
Runner.runJSExample("io/vertx/example/apex/realtime/server.js");
46-
}
49+
Runner.runJSExample("io/vertx/example/apex/realtime/chat.js");
50+
}
4751
}
4852

4953
static class JSSessionsRunner {
@@ -80,6 +84,10 @@ public static void main(String[] args) {
8084
}
8185
}
8286

87+
static class GroovyRealtimeChatRunner {
88+
public static void main(String[] args) { Runner.runGroovyExample("io/vertx/example/apex/realtime/chat.groovy"); }
89+
}
90+
8391
static class GroovyRealtimeRunner {
8492
public static void main(String[] args) {
8593
Runner.runGroovyExample("io/vertx/example/apex/realtime/server.groovy");

0 commit comments

Comments
 (0)