Creating a Websocket Chat Application with Vert.x and Java
November 13th, 2013 by Micha KopsVert.x is a modern, lightweight framework to build high performance applications running on the Java Virtual Machine. The framework is polyglot so that you’re able to write your application in Java, Groovy, Ruby, Python or even JavaScript.
In addition it offers a nice component system, an actor-like concurrency model a distributed event bus and an elegant API to create scalable applications in no time.
In the following tutorial we’re going to build a websocket chat by creating a HTTP server and the websocket server using Vert.x, Java and Maven.
Contents
The Chat Application
We want to build a chat application where a user is able to enter a chatroom from a list of available rooms, and receives updates for the specific chat room.
As I am lazy – for the client side I am going to recycle the client code (HTML, CSS, Javascript) from my tutorial “Creating a Chat Application using Java EE 7, Websockets and GlassFish 4“.
On the server side we’re going to set up an HTTP server to serve the HTML file and the other web resources like CSS, Javascripts etc listening on port 8080 and a websocket server listening on port 8090 (we also could have used on server-instance for both).
Project Setup and Dependencies
Using Apache Maven, there is an archetype we may use to speed up the project setup process: io.vertx:vertx-maven-archetype:2.0.0-final
This is my generated pom.xml (shortened, for the full descriptor file please have a look at my git repo):
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.hascode.tutorial</groupId> <artifactId>vertx-websocket-chat</artifactId> <packaging>jar</packaging> <version>1.0.0</version> <name>Vert.x Websocket Chat</name> <parent> <groupId>org.sonatype.oss</groupId> <artifactId>oss-parent</artifactId> <version>7</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <vertx.pullInDeps>false</vertx.pullInDeps> <module.name>${project.groupId}~${project.artifactId}~${project.version}</module.name> <vertx.version>2.0.0-final</vertx.version> <vertx.testtools.version>2.0.0-final</vertx.testtools.version> <maven.compiler.plugin.version>3.0</maven.compiler.plugin.version> <maven.resources.plugin.version>2.6</maven.resources.plugin.version> <maven.clean.plugin.version>2.5</maven.clean.plugin.version> <maven.vertx.plugin.version>2.0.0-final</maven.vertx.plugin.version> <maven.surefire.plugin.version>2.14</maven.surefire.plugin.version> <maven.failsafe.plugin.version>2.14</maven.failsafe.plugin.version> <maven.surefire.report.plugin.version>2.14</maven.surefire.report.plugin.version> <maven.javadoc.plugin.version>2.9</maven.javadoc.plugin.version> <maven.dependency.plugin.version>2.7</maven.dependency.plugin.version> </properties> [..] <dependencies> <!--Vertx provided dependencies --> <dependency> <groupId>io.vertx</groupId> <artifactId>vertx-core</artifactId> <version>${vertx.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>io.vertx</groupId> <artifactId>vertx-platform</artifactId> <version>${vertx.version}</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>io.vertx</groupId> <artifactId>vertx-maven-plugin</artifactId> <version>${maven.vertx.plugin.version}</version> <executions> <execution> <id>PullInDeps</id> <phase>prepare-package</phase> <goals> <goal>pullInDeps</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven.compiler.plugin.version}</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>${maven.resources.plugin.version}</version> <executions> <execution> <id>copy-mod-to-target</id> <phase>process-classes</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <overwrite>true</overwrite> <outputDirectory>target/mods/${module.name}</outputDirectory> <resources> <resource> <directory>target/classes</directory> </resource> </resources> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>${maven.dependency.plugin.version}</version> <executions> <execution> <id>copy-mod-dependencies-to-target</id> <phase>process-classes</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>target/mods/${module.name}/lib</outputDirectory> <includeScope>runtime</includeScope> </configuration> </execution> </executions> </plugin> [..] <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptors> <descriptor>src/main/assembly/mod.xml</descriptor> </descriptors> </configuration> <executions> <execution> <id>assemble</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
Chat Server Verticle
We’re creating one verticle to create a http server running on port 8080 and a websocket server running in port 8090.
First we need to inherit from org.vertx.java.platform.Verticle here and override the start method.
package com.hascode.tutorial.vertx_tutorial; import java.io.File; import java.io.IOException; import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.vertx.java.core.Handler; import org.vertx.java.core.buffer.Buffer; import org.vertx.java.core.eventbus.EventBus; import org.vertx.java.core.http.HttpServerRequest; import org.vertx.java.core.http.RouteMatcher; import org.vertx.java.core.http.ServerWebSocket; import org.vertx.java.core.logging.Logger; import org.vertx.java.platform.Verticle; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; public class WebserverVerticle extends Verticle { @Override public void start() { final Pattern chatUrlPattern = Pattern.compile("/chat/(\\w+)"); final EventBus eventBus = vertx.eventBus(); final Logger logger = container.logger(); // 1) HTTP Server // 2) Websockets Chat Server } }
HTTP Server
The following cheap HTTP server is there to serve the HTML file and the Javascript and CSS resources (like Bootstrap, jQuery etc..).
We’re using a RouteMatcher here to handle different URLs and basically that’s all.
RouteMatcher httpRouteMatcher = new RouteMatcher().get("/", new Handler<HttpServerRequest>() { @Override public void handle(final HttpServerRequest request) { request.response().sendFile("web/chat.html"); } }).get(".*\\.(css|js)$", new Handler<HttpServerRequest>() { @Override public void handle(final HttpServerRequest request) { request.response().sendFile("web/" + new File(request.path())); } }); vertx.createHttpServer().requestHandler(httpRouteMatcher).listen(8080, "localhost");
Websockets Server
The websocket server listens on port 8090 for connections.
First of all we’re rejecting every request that does not match our specified “path”. Otherwise we’re assigning the connection id to the chat room.
Vert.x offers a shared data structure that we’re using here to make this information available to all workers.
Afterwards we’re adding a close handler to remove the session from the data pool when the connection is closed.
Finally when the client pushes a message to the websocket server, we’re adding the current date to the chat message in the JSON format and we’re broadcasting the message to all registered chatters for the specific chatroom using the Vert.x EventBus and the connection id .
vertx.createHttpServer().websocketHandler(new Handler<ServerWebSocket>() { @Override public void handle(final ServerWebSocket ws) { final Matcher m = chatUrlPattern.matcher(ws.path()); if (!m.matches()) { ws.reject(); return; } final String chatRoom = m.group(1); final String id = ws.textHandlerID(); logger.info("registering new connection with id: " + id + " for chat-room: " + chatRoom); vertx.sharedData().getSet("chat.room." + chatRoom).add(id); ws.closeHandler(new Handler<Void>() { @Override public void handle(final Void event) { logger.info("un-registering connection with id: " + id + " from chat-room: " + chatRoom); vertx.sharedData().getSet("chat.room." + chatRoom).remove(id); } }); ws.dataHandler(new Handler<Buffer>() { @Override public void handle(final Buffer data) { ObjectMapper m = new ObjectMapper(); try { JsonNode rootNode = m.readTree(data.toString()); ((ObjectNode) rootNode).put("received", new Date().toString()); String jsonOutput = m.writeValueAsString(rootNode); logger.info("json generated: " + jsonOutput); for (Object chatter : vertx.sharedData().getSet("chat.room." + chatRoom)) { eventBus.send((String) chatter, jsonOutput); } } catch (IOException e) { ws.reject(); } } }); } }).listen(8090);
Vert.x Module Configuration
This step is optional but it allows us to capsule the application as a Vert.x module by adding the following mod.json in src/main/resources:
{ "main":"com.hascode.tutorial.vertx_tutorial.WebserverVerticle", "description":"hasCode.com Vert.x Websocket Chat Sample", "author": "Micha Kops", "homepage": "https://www.hascode.com/" }
The Client Side
Nothing special here – we’re opening a new connection to the web socket at ws://0.0.0.0:8090/chat/CHATROOMNAME.
The user may send a JSON formatted message to the server, a callback is defined for updates from the server that updates the client’s view.
Finally when leaving a chat room, the websocket connection is closed.
The javascript (excerpt):
<script> var wsocket; var serviceLocation = "ws://0.0.0.0:8090/chat/"; var $nickName; var $message; var $chatWindow; var room = ''; function onMessageReceived(evt) { var msg = JSON.parse(evt.data); // native API var $messageLine = $('<tr><td class="received">' + msg.received + '</td><td class="user label label-info">' + msg.sender + '</td><td class="message badge">' + msg.message + '</td></tr>'); $chatWindow.append($messageLine); } function sendMessage() { var msg = '{"message":"' + $message.val() + '", "sender":"' + $nickName.val() + '", "received":""}'; wsocket.send(msg); $message.val('').focus(); } function connectToChatserver() { room = $('#chatroom option:selected').val(); wsocket = new WebSocket(serviceLocation + room); wsocket.onmessage = onMessageReceived; } function leaveRoom() { wsocket.close(); $chatWindow.empty(); $('.chat-wrapper').hide(); $('.chat-signin').show(); $nickName.focus(); } $(document).ready(function() { $nickName = $('#nickname'); $message = $('#message'); $chatWindow = $('#response'); $('.chat-wrapper').hide(); $nickName.focus(); $('#enterRoom').click(function(evt) { evt.preventDefault(); connectToChatserver(); $('.chat-wrapper h2').text('Chat # '+$nickName.val() + "@" + room); $('.chat-signin').hide(); $('.chat-wrapper').show(); $message.focus(); }); $('#do-chat').submit(function(evt) { evt.preventDefault(); sendMessage() }); $('#leave-room').click(function(){ leaveRoom(); }); }); </script>
The html (excerpt):
<div class="container chat-signin"> <form class="form-signin"> <h2 class="form-signin-heading">Chat sign in</h2> <label for="nickname">Nickname</label> <input type="text" class="input-block-level" placeholder="Nickname" id="nickname"> <div class="btn-group"> <label for="chatroom">Chatroom</label> <select size="1" id="chatroom"> <option>arduino</option> <option>java</option> <option>groovy</option> <option>scala</option> </select> </div> <button class="btn btn-large btn-primary" type="submit" id="enterRoom">Sign in</button> </form> </div> <div class="container chat-wrapper"> <form id="do-chat"> <h2 class="alert alert-success"></h2> <table id="response" class="table table-bordered"></table> <fieldset> <legend>Enter your message..</legend> <div class="controls"> <input type="text" class="input-block-level" placeholder="Your message..." id="message" style="height:60px"/> <input type="submit" class="btn btn-large btn-block btn-primary" value="Send message" /> <button class="btn btn-large btn-block" type="button" id="leave-room">Leave room</button> </div> </fieldset> </form> </div>
Running the Application
Now it’s time to start up the application – this is done easy and very fast using maven and the following command:
mvn package vertx:runMod
Now you should be able to see a similar output and to play around with the chat using two browser instances – or alternatively please feel free to have a look at the screencast.
Screencast
This is the final running application emulating a chat using two different browsers as screencast on YouTube.
Creating a Fat Jar
If you’d like to create one single jar file with all dependencies and stuff packaged to run the full application, building a so called fat jar is your solution.
First of all you need to download the vertx binaries from the website – afterwards you’re able to build and run your fat jar like this:
$ mvn package $ cd target/ $ vertx fatjar com.hascode.tutorial~vertx-websocket-chat~1.0.0 Attempting to make a fat jar for module com.hascode.tutorial~vertx-websocket-chat~1.0.0 Succeeded in making fat jar $ java -jar vertx-websocket-chat-1.0.0-fat.jar Jan 23, 2014 9:04:25 PM org.vertx.java.core.logging.impl.JULLogDelegate info INFO: Succeeded in deploying module
Alternatively if you’re using Gradle you might use the gradle target and simply run
gradle fatjar
Client Implementation in Java
Please feel free to have a look at my article “Creating different Websocket Chat Clients in Java” for a client implementation in Java.
Circuit Breakers and Vert.x
Vert.x offers a circuit-breaker implementation and also integrates well with Hystrix, if interested, please feel free to read my tutorial: “Resilient Architecture in Practice – Circuit Breakers for Java: Failsafe, Javaslang, Hystrix and Vert.x”
Tutorial Sources
Please feel free to download the tutorial sources from my Bitbucket repository, fork it there or clone it using Git:
git clone https://bitbucket.org/hascode/vertx-websocket-chat.git
Resources
Websocket Chat Articles
I have written other tutorials about websocket server and client implementations, please feel to read further:
- Creating a Chat Application using Java EE 7, Websockets and GlassFish 4
- Creating different Websocket Chat Clients in Java
- Writing a Websocket Chat in Go
Article Updates
- 2018-06-01: Embedded YouTube video removed (GDPR/DSGVO).
- 2017-02-14: Link to circuit-breaker article added.
- 2016-10-29: Link to Go websocket chat implementation added.
- 2014-11-09: Article about websocket client implementation in Java linked.
Tags: actor, chat, html5, io, nonblocking, server, vert.x, websocket
November 15th, 2013 at 7:36 am
After cloning the vertx-websocket-chat Git repo via Bitbucket, I ran the mvn compile command and build was successful. However, when I ran the mvn vertx:runMod command, the chat app does not seem to start (i.e., two browser instances do not appear, and if I manually start two browser instances and enter the URLs specified in your article, the web pages are not found). Below is console output after mvn vertx:runMod. Please note PlatformManagerException ERROR and advise:
C:\Users\jed32\My Documents\vertx-websocket-chat>mvn vertx:runMod
[INFO] Scanning for projects…
Downloading: http://repo.maven.apache.org/maven2/io/vertx/vertx-maven-plugin/2.
.0-final/vertx-maven-plugin-2.0.0-final.pom
Downloaded: http://repo.maven.apache.org/maven2/io/vertx/vertx-maven-plugin/2.0
0-final/vertx-maven-plugin-2.0.0-final.pom (4 KB at 11.1 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/io/vertx/vertx-maven-plugin/2.
.0-final/vertx-maven-plugin-2.0.0-final.jar
Downloaded: http://repo.maven.apache.org/maven2/io/vertx/vertx-maven-plugin/2.0
0-final/vertx-maven-plugin-2.0.0-final.jar (17 KB at 83.2 KB/sec)
[INFO]
[INFO] ————————————————————————
[INFO] Building Vert.x Websocket Chat 1.0.0
[INFO] ————————————————————————
[INFO]
[INFO] — vertx-maven-plugin:2.0.0-final:runMod (default-cli) @ vertx-websocke
-chat —
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugin-tools/
aven-plugin-tools-api/3.2/maven-plugin-tools-api-3.2.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugin-tools/m
ven-plugin-tools-api/3.2/maven-plugin-tools-api-3.2.pom (3 KB at 47.8 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugin-tools/
aven-plugin-tools/3.2/maven-plugin-tools-3.2.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugin-tools/m
ven-plugin-tools/3.2/maven-plugin-tools-3.2.pom (17 KB at 206.9 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugin-tools/
aven-plugin-tools-annotations/3.2/maven-plugin-tools-annotations-3.2.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugin-tools/m
ven-plugin-tools-annotations/3.2/maven-plugin-tools-annotations-3.2.pom (5 KB a
66.5 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugin-tools/
aven-plugin-annotations/3.2/maven-plugin-annotations-3.2.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugin-tools/m
ven-plugin-annotations/3.2/maven-plugin-annotations-3.2.pom (2 KB at 20.3 KB/se
)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/maven-artifac
/3.0/maven-artifact-3.0.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/maven-artifact
3.0/maven-artifact-3.0.pom (2 KB at 24.1 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/maven/3.0/mav
n-3.0.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/maven/3.0/mave
-3.0.pom (22 KB at 274.0 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/
5/maven-parent-15.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/1
/maven-parent-15.pom (24 KB at 300.5 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-uti
s/2.0.4/plexus-utils-2.0.4.pom
Downloaded: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-util
/2.0.4/plexus-utils-2.0.4.pom (4 KB at 52.5 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/asm/asm/3.3.1/asm-3.3.1.pom
Downloaded: http://repo.maven.apache.org/maven2/asm/asm/3.3.1/asm-3.3.1.pom (26
B at 3.3 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/asm/asm-parent/3.3.1/asm-paren
-3.3.1.pom
Downloaded: http://repo.maven.apache.org/maven2/asm/asm-parent/3.3.1/asm-parent
3.3.1.pom (5 KB at 54.2 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/asm/asm-commons/3.3.1/asm-comm
ns-3.3.1.pom
Downloaded: http://repo.maven.apache.org/maven2/asm/asm-commons/3.3.1/asm-commo
s-3.3.1.pom (417 B at 6.6 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/asm/asm-tree/3.3.1/asm-tree-3.
.1.pom
Downloaded: http://repo.maven.apache.org/maven2/asm/asm-tree/3.3.1/asm-tree-3.3
1.pom (406 B at 6.4 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-arc
iver/2.1.1/plexus-archiver-2.1.1.pom
Downloaded: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-arch
ver/2.1.1/plexus-archiver-2.1.1.pom (3 KB at 29.5 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-io/
.0.3/plexus-io-2.0.3.pom
Downloaded: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-io/2
0.3/plexus-io-2.0.3.pom (2 KB at 26.9 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/com/thoughtworks/qdox/qdox/1.1
.1/qdox-1.12.1.pom
Downloaded: http://repo.maven.apache.org/maven2/com/thoughtworks/qdox/qdox/1.12
1/qdox-1.12.1.pom (18 KB at 220.3 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/codehaus/codehaus-parent/4
codehaus-parent-4.pom
Downloaded: http://repo.maven.apache.org/maven2/org/codehaus/codehaus-parent/4/
odehaus-parent-4.pom (5 KB at 74.7 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/1.7.2/slf4
-api-1.7.2.pom
Downloaded: http://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/1.7.2/slf4j
api-1.7.2.pom (3 KB at 41.7 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/slf4j/slf4j-parent/1.7.2/s
f4j-parent-1.7.2.pom
Downloaded: http://repo.maven.apache.org/maven2/org/slf4j/slf4j-parent/1.7.2/sl
4j-parent-1.7.2.pom (12 KB at 183.0 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugin-tools/
aven-plugin-tools-annotations/3.2/maven-plugin-tools-annotations-3.2.jar
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugin-tools/
aven-plugin-tools-api/3.2/maven-plugin-tools-api-3.2.jar
Downloading: http://repo.maven.apache.org/maven2/asm/asm-commons/3.3.1/asm-comm
ns-3.3.1.jar
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugin-tools/
aven-plugin-annotations/3.2/maven-plugin-annotations-3.2.jar
Downloading: http://repo.maven.apache.org/maven2/asm/asm/3.3.1/asm-3.3.1.jar
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugin-tools/m
ven-plugin-annotations/3.2/maven-plugin-annotations-3.2.jar (15 KB at 85.6 KB/s
c)
Downloading: http://repo.maven.apache.org/maven2/asm/asm-tree/3.3.1/asm-tree-3.
.1.jar
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugin-tools/m
ven-plugin-tools-annotations/3.2/maven-plugin-tools-annotations-3.2.jar (39 KB
t 191.5 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-arc
iver/2.1.1/plexus-archiver-2.1.1.jar
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugin-tools/m
ven-plugin-tools-api/3.2/maven-plugin-tools-api-3.2.jar (23 KB at 104.1 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-io/
.0.3/plexus-io-2.0.3.jar
Downloaded: http://repo.maven.apache.org/maven2/asm/asm/3.3.1/asm-3.3.1.jar (43
KB at 181.9 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/com/thoughtworks/qdox/qdox/1.1
.1/qdox-1.12.1.jar
Downloaded: http://repo.maven.apache.org/maven2/asm/asm-commons/3.3.1/asm-commo
s-3.3.1.jar (38 KB at 126.4 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/1.7.2/slf4
-api-1.7.2.jar
Downloaded: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-io/2
0.3/plexus-io-2.0.3.jar (57 KB at 330.9 KB/sec)
Downloaded: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-arch
ver/2.1.1/plexus-archiver-2.1.1.jar (181 KB at 827.1 KB/sec)
Downloaded: http://repo.maven.apache.org/maven2/com/thoughtworks/qdox/qdox/1.12
1/qdox-1.12.1.jar (176 KB at 865.0 KB/sec)
Downloaded: http://repo.maven.apache.org/maven2/asm/asm-tree/3.3.1/asm-tree-3.3
1.jar (22 KB at 75.0 KB/sec)
Downloaded: http://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/1.7.2/slf4j
api-1.7.2.jar (26 KB at 148.1 KB/sec)
log4j:WARN No appenders could be found for logger (io.netty.util.internal.loggi
g.InternalLoggerFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more i
fo.
[ERROR]
org.vertx.java.platform.PlatformManagerException: Module com.hascode.tutorial~v
rtx-websocket-chat~1.0.0 not found in any repositories
at org.vertx.java.platform.impl.DefaultPlatformManager.getModule(Defaul
PlatformManager.java:985)
at org.vertx.java.platform.impl.DefaultPlatformManager.doInstallMod(Def
ultPlatformManager.java:974)
at org.vertx.java.platform.impl.DefaultPlatformManager.deployModuleFrom
ileSystem(DefaultPlatformManager.java:830)
at org.vertx.java.platform.impl.DefaultPlatformManager.access$100(Defau
tPlatformManager.java:55)
at org.vertx.java.platform.impl.DefaultPlatformManager$1.run(DefaultPla
formManager.java:151)
at org.vertx.java.platform.impl.DefaultPlatformManager$11.run(DefaultPl
tformManager.java:359)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor
java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecuto
.java:615)
at java.lang.Thread.run(Thread.java:724)
[INFO] ————————————————————————
[INFO] BUILD SUCCESS
[INFO] ————————————————————————
[INFO] Total time: 5.819s
[INFO] Finished at: Fri Nov 15 00:52:56 CST 2013
[INFO] Final Memory: 6M/16M
[INFO] ————————————————————————
C:\Users\jed32\My Documents\vertx-websocket-chat>
November 15th, 2013 at 6:30 pm
Hi Jim,
thanks for your input! Running
mvn package vertx:runMod
instead should do the trick.November 16th, 2013 at 9:02 am
Micha,
Thanks for your reply to my inquiry. I followed your instruction and now console output indicates the server is running. However, after running two instances of Chrome browser and entering localhost:8080 URLs, I see the Chat dialogs, but after signing two users into the ‘arduino’ chat room, I’m unable to get any Message output in either browser. I looked at your demo on YouTube, and I don’t see any similar console output following ‘[INFO] CTRL-C to stop server. Do any Vert.x Jar files need to be in the vertx-websocket-chat folder? Please review my console output below; I appreciate your help:
C:\Users\jed32\My Documents\vertx-websocket-chat>mvn package vertx:runMod
[INFO] Scanning for projects…
[INFO]
[INFO] ———————————————————————–
[INFO] Building Vert.x Websocket Chat 1.0.0
[INFO] ———————————————————————–
[INFO]
[INFO] — maven-enforcer-plugin:1.0:enforce (enforce-maven) @ vertx-websocket
hat —
[INFO]
[INFO] — maven-resources-plugin:2.6:resources (default-resources) @ vertx-we
ocket-chat —
[INFO] Using ‘UTF-8′ encoding to copy filtered resources.
[INFO] Copying 11 resources
[INFO]
[INFO] — maven-compiler-plugin:3.0:compile (default-compile) @ vertx-websock
-chat —
[INFO] Nothing to compile – all classes are up to date
[INFO]
[INFO] — maven-resources-plugin:2.6:copy-resources (copy-mod-to-target) @ ve
x-websocket-chat —
[INFO] Using ‘UTF-8′ encoding to copy filtered resources.
[INFO] Copying 18 resources
[INFO]
[INFO] — maven-dependency-plugin:2.7:copy-dependencies (copy-mod-dependencie
to-target) @ vertx-websocket-chat —
[INFO]
[INFO] — maven-resources-plugin:2.6:testResources (default-testResources) @
rtx-websocket-chat —
[INFO] Using ‘UTF-8′ encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory C:\Users\jed32\My Documents\vertx-w
socket-chat\src\test\resources
[INFO]
[INFO] — maven-compiler-plugin:3.0:testCompile (default-testCompile) @ vertx
ebsocket-chat —
[INFO] No sources to compile
[INFO]
[INFO] — maven-surefire-plugin:2.14:test (default-test) @ vertx-websocket-ch
—
[INFO] No tests to run.
[INFO]
[INFO] >>> maven-surefire-report-plugin:2.14:report-only (generate-test-report
@ vertx-websocket-chat >>>
[INFO]
[INFO] — maven-enforcer-plugin:1.0:enforce (enforce-maven) @ vertx-websocket
hat —
[INFO]
[INFO] <<< maven-surefire-report-plugin:2.14:report-only (generate-test-report
@ vertx-websocket-chat <<<
[INFO]
[INFO] — maven-surefire-report-plugin:2.14:report-only (generate-test-report
@ vertx-websocket-chat —
[WARNING] Unable to locate Test Source XRef to link to – DISABLED
[INFO]
[INFO] — vertx-maven-plugin:2.0.0-final:pullInDeps (PullInDeps) @ vertx-webs
ket-chat —
[INFO]
[INFO] — maven-jar-plugin:2.3.2:jar (default-jar) @ vertx-websocket-chat —
[INFO]
[INFO] — maven-assembly-plugin:2.2-beta-5:single (assemble) @ vertx-websocke
chat —
[INFO] Reading assembly descriptor: src/main/assembly/mod.xml
[INFO] Building zip: C:\Users\jed32\My Documents\vertx-websocket-chat\target\v
tx-websocket-chat-1.0.0-mod.zip
[INFO]
[INFO] — vertx-maven-plugin:2.0.0-final:runMod (default-cli) @ vertx-websock
-chat —
log4j:WARN No appenders could be found for logger (io.netty.util.internal.logg
g.InternalLoggerFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more
fo.
[INFO] CTRL-C to stop server
November 16th, 2013 at 4:15 pm
Hi, I’m not able to reproduce your problem atm.
Is there a firewall blocking tcp connections, does it work when using 0.0.0.0 instead of “localhost”? Do you receive any javascript errors e.g. in firebug or websocket errors e.g. in Chrome > Developer Tools > Network > Filter – Websockets > Websocket Frames?
November 17th, 2013 at 6:06 pm
Hi Micha, still do not see output after Send Message. After Sign in on separate Chrome browser instances, in Developer Tools > Network > Websockets, I see Status ‘Success’ in regard to websocket server (arduino 0.0.0.0.chat). I also see its Type as ‘Pending’. Before that, however, when the chat.html page loads in each browser instance, I see in Developer Tools > Network the following sequence: GET /resource/js –> jquery-1.10.2.min.map Status ’404′. Please note that I cloned your repo to my local Windows 7 machine running Windows Firewall, which blocks Inbound connections that do not have firewall rules to allow connection. Outbound connections are allowed. In the past, I’ve been able to run WebRTC apps that rely on the WebSocket API on this machine. Thanks very much for your guidance.
November 18th, 2013 at 6:57 pm
Interesting :)
Just out of curiosity – I’ve created a new branch named “jim” with http and websocket server running on the same port and both referring to localhost (server and client):
https://bitbucket.org/hascode/vertx-websocket-chat/src?at=jim
Does this change anything in your environment?
November 19th, 2013 at 11:17 am
Micha –
I cloned the new branch named “jim” (with http and websocket server running on same port and both referring to localhost). As before, does not produce output after Send Message. Below are some observations:
1. See in Chrome Developer Tools > Console:
[warning icon] event.returnValue is deprecated. Please use the standard event.preventDefault() instead.
[error icon] WebSocket is already in CLOSING or CLOSED state. (index):1
[error icon] WebSocket is already in CLOSING or CLOSED state. (index):94
2. See in Chrome Developer Tools > Network > Headers tab [parsed view]:
Request URL:http://localhost:8080/resource/js/jquery-1.10.2.min.map
Request Method:GET
Status Code:404 OK
Request Headers view source [link to source view]
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Host:localhost:8080
Referer:http://localhost:8080/
User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36
X-Source-Map-Request-From:inspector
Response Headers view source [link to source view]
Content-Length:0
3. See in Chrome Developer Tools > Resources tab, with Frames tree expanded:
localhost/ > [error icon] Web Socket is already in CLOSING or CLOSED state
Thanks for all your efforts to resolve this issue. I’ll continue to troubleshoot.
November 20th, 2013 at 6:47 pm
have tried to run the application with the firewall switched off just to be sure? perhaps im going to take a test round on a windows vm with a fat-jar build.
November 26th, 2013 at 6:50 am
Micha,
I ran the application with firewall switched off … no help. See port 8090 open, so websocket server is listening. Logging (log4j) is not configured correctly; could that be causing problem?
Thanks, Jim D.
December 3rd, 2013 at 5:51 pm
Hi,
I’ve tested the version using the same ports on a Windows 7 machine and it worked without a problem. I’ve added the fat jar as a download for easy testing here: https://bitbucket.org/hascode/vertx-websocket-chat/downloads/vertx-websocket-chat-1.0.0-fat-same-port.jar
Running it with Oracle JDK 1.7 with
java -jar vertx-websocket-chat-1.0.0-fat-same-port.jar
worked for me.January 23rd, 2014 at 4:11 pm
Hi,
I would like to know how to generate fatjar from vertx project
could you explain
Thanks
January 23rd, 2014 at 8:12 pm
Hi Amin,
thanks for your feedback! I have updated the tutorial to answer your question.
Cheers
Micha
March 31st, 2014 at 10:45 am
I reproduced the same issue as Jim, I just changed in chat html:
var serviceLocation = “ws://0.0.0.0:8090/chat/”;
to
var serviceLocation = “ws://localhost:8090/chat/”;
then it worked fine for me, no need to use the different ports.
FYI, I m using last chrome on Windows 7 and firewall is on.
Regards,
June 5th, 2014 at 2:37 pm
I have written the whole program and I run it in CMD but when i open the browser and go to localhosts, it says the webpage is not available. Where am I going wrong?
November 4th, 2014 at 11:35 am
Is it possible to have client using JavaFX. Is there some tutorial for that. How can I have multiple instances of program using JavaFX, that communicates with server and return data in real-time like in this example where client is runned in browser(s).
November 4th, 2014 at 6:33 pm
Hi Davor,
sure! You could use the Jetty websocket client API to connect to the chat server without using a browser (you might use an embedded browser in Java-FX though ;)
http://www.eclipse.org/jetty/documentation/current/jetty-websocket-client-api.html
Cheers,
Micha
November 4th, 2014 at 7:48 pm
On the other side – I’ve nearly finished my article on Java’s websocket client API .. could add some Java-FX and your problem is solved.
March 3rd, 2015 at 7:34 am
I tired the example on TJWS and as many reported couldn’t see messages. I looked in log and there is an exception:
java.lang.NoClassDefFoundError: javax/json/Json
at com.hascode.tutorial.ChatMessageDecoder.decode(ChatMessageDecoder.java:24)
at com.hascode.tutorial.ChatMessageDecoder.decode(ChatMessageDecoder.java:12)
at rogatkin.wskt.SimpleSession$SimpleMessageHandler.processText(SimpleSession.java:1110)
at rogatkin.wskt.SimpleSession$SimpleMessageHandler.processText(SimpleSession.java:1085)
at rogatkin.wskt.SimpleSession.parseFrame(SimpleSession.java:325)
at rogatkin.wskt.SimpleSession.run(SimpleSession.java:143)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Can someone point where I can get the JSON library?
March 3rd, 2015 at 7:41 am
Resolved, I downloaded javax.json-1.0.1.jar from http://www.java2s.com/Code/Jar/j/Downloadjavaxjson102jar.htm
and added in WEB-INF/lib and it works now. Cool, thanks for the amazing tutorial.
March 3rd, 2015 at 7:22 pm
Hi,
thanks for your kind remarks! I’m glad it’s working for you now. Now I’m possibly to late to share a the following link to include the new Java JSON API into your project using common build tools like Maven, Gradle, Ivy etc .. perhaps you still might need it so here it is: http://mavenrepository.com/artifact/javax.json/javax.json-api/1.0.
Best wishes
Micha
April 9th, 2015 at 5:36 am
Hi there,
This is a very usefull article . Can you write an Article about deploying vertx to Heroku?
Best Wishes
April 9th, 2015 at 6:47 am
Hi,
possibly yes, but I can’t promise it :)
Meanwhile perhaps this sample project on GitHub may be a help for you there: https://github.com/mthenw/vertx-sample
February 27th, 2020 at 1:21 pm
How to send image,document like doc,PDF etc over the vertx WebSocket.Please share if you have any examples.