IRC-style chat with TCP server and event bus

Exclusive offer: get 50% off this eBook here
Instant Vert.x [Instant]

Instant Vert.x [Instant] — Save 50%

A kick-start for rapid development of asynchronous network applications using the Vert.x framework with this book and ebook

£8.99    £4.50
by Simone Scarduzio | August 2013 | Java Open Source Web Development

In this article by Simone Scarduzio, the author of Instant Vert.x, a brief and step-wise explanation of creating an Internet Relay Chat has been described. This chat includes a main TCP server, and an event bus for communicating between the different connected clients. In this type of architecture, a one-to-one, one-to-many, many-to-one, and many-to-many communications are possible.

As an example, let's show off a bit of what an event bus can do. This is a TCP server that fans out messages received from one client to the rest of the connected clients.

This is an event bus-based variation of the classic "fan out" example that can be found in official documentation of Vert.x. The original example keeps a set of client sockets (one for every connected client) and iterates over them every time a new message is received. With this one however, we will demonstrate how the publish-subscribe feature offered by this framework, keeps the code simple by saving the hassle to keep updated and iterate over a set of client sockets.

(For more resources related to this topic, see here.)

Step 1 – fresh start

  1. In a new folder called, for example, 1_PubSub_Chat, let's open our editor of choice and create here a file called pubsub_chat.js.
  2. Also, make sure that you have a terminal window open and you moved into the newly created project directory.

Step 2 – creating the TCP server

TCP servers are called net servers in Vert.x. Creating and using a net server is really similar to HTTP servers:

  1. Obtain the vertx bridge object to access the framework features:

    var vertx = require('vertx'); /* 1 */
    var netServer = vertx.createNetServer(); /* 2 */
    netServer.listen(1234); /* 3 */

  2. Ask Vert.x to create a TCP server (called NetServer in Vert.x).
  3. Actually, start the server by telling it to listen on TCP port 1234.

    Let's test whether this works. This time we need another terminal to run the telnet command:

    $ telnet localhost 1234

    The terminal should now be connected and waiting to send/receive characters. If you have "connection refused" errors, make sure the server is running.

Step 3 – adding a connect handler

Now, we need to place a block of code to be executed as soon as a client connects:

  1. Define a handler function. This function will be called every time a client connects to the server:

    var vertx = require('vertx')
    var server = vertx.createNetServer().connectHandler(
    function(socket) {
    // Composing a client address string
    addr = socket.remoteAddress();
    addr = addr.ipaddress + addr.port;
    socket.write('Welcome to the chat ' + addr + '!');
    }).listen(1234)

    A NetServer connect handler accepts the socket object as a parameter; this object is our gateway to reading, writing, or closing the connection to a client.

  2. Use the socket object to write a greeting to the newly connected clients.
  3. If we test this one as in step 2 (Step 2 – creating the TCP server), we see that the server now welcomes us with a message containing an identifier of the client as its origin host and origin port.

Step 4 – adding a data handler

We just learned how to execute a block of code at the moment in which the client connects. However now we are interested in doing something else at the time when we receive new data from a client connection.

The socket object we used in the previous step for writing data back to the client, accepts a handler function too: the data handler. Let's add one:

  1. Add a data handler function to the socket object. This is going to be called every time the client sends a new string of data:

    var vertx = require('vertx') var server = vertx.createNetServer().connectHandler( function(socket) { // Composing a client address string addr = socket.remoteAddress(); addr = addr.ipaddress + addr.port; socket.write('Welcome to the chat ' + addr + '!'); socket.dataHandler(function(data) { var now = new Date(); now = now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds(); var msg = now + ' <' + addr + '> ' + data; socket.write(msg); }) }).listen(1234)

  2. React to the new data event by writing the same data back to the socket (plus a prefix).

    What we have now is a sort of an echo server, which returns back to the sender the same message with a prefix string.

Step 5 – adding the event bus magic

The base requirement of a chat server is that every time a client sends a message, the rest of the connected clients should receive it. We will use event bus, the messaging service provided by the framework, to send (publish) received messages to a broadcast address. Each client will subscribe to the address upon connection and receive other clients' messages from there:

  1. Add a data handler function to the socket object:

    var vertx = require('vertx') var server = vertx.createNetServer().connectHandler( function(socket) { // Composing a client address string addr = socket.remoteAddress(); addr = addr.ipaddress + addr.port; socket.write('Welcome to the chat ' + addr + '!'); vertx.eventBus.registerHandler('broadcast_address', function(event){ socket.write(event); }); socket.dataHandler(function(data) { var now = new Date(); now = now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds(); var msg = now + ' <' + addr + '> ' + data; vertx.eventBus.publish('broadcast_address', msg); }) }).listen(1234)

  2. As soon as a client connects, they listen to the event bus for new data to be published on the address broadcast_address.
  3. When a client sends a string of characters to the server, this data is published to the broadcast address, triggering a handler function that writes the string to all the clients' sockets.
  4. The chat server is now complete! To try it out, just open three terminals:
    • Terminal 1: $ vertx run pubsub_chat.js
    • Terminal 2: $ telnet localhost 1234
    • Terminal 3: $ telnet localhost 1234
  5. Now, we have a server and two clients running and connected. Type something in terminal 2 or 3 and see the message being broadcast to both the other windows:

    $ telnet localhost 1234
    Trying ::1...
    Connected to localhost.
    Escape character is '^]'.
    Hello from terminal two!
    13:6:56 <0:0:0:0:0:0:0:155991> Hello from terminal two!
    13:7:24 <0:0:0:0:0:0:0:155992> Hi there, here's terminal three!
    13:7:56 <0:0:0:0:0:0:0:155992> Great weather today!

Step 6 – Organizing a more complex project

Since Vert.x is a polyglot platform, we can choose to write an application (or a part of it) in either of the many supported languages. The granularity of the language choice is at verticle level. It's important to give a good architecture to a non-trivial project from the beginning.

Follow this list of generic principles to avoid performance bottlenecks or the need for massive refactoring in the future:

  1. Wrap synchronous libraries or legacy code inside a worker verticle (or a module). This will keep the blocking code away from the event loop threads.
  2. Divide the problem in isolated domains and write a verticle to handle each of them (for example, database persistor verticle, web server verticle, authenticator verticle, and cache manager verticle).
  3. Use a startup verticle. This will be the single entry point to the application. Its responsibilities will be to:
    • Validate the configuration file
    • Programmatically deploy other verticles in the correct order
    • Decide how many instances of a verticle to create (the decision might depend on the environment: for example, the amount of available processors)
    • Register periodic tasks

Summary:

In this article, we learned in a step-wise procedure how we can create an Internet Relay Chat using the TCP server, and interconnect the server with the clients using an event bus, and enable different types of communication between them.

Resources for Article:


Further resources on this subject:


Instant Vert.x [Instant] A kick-start for rapid development of asynchronous network applications using the Vert.x framework with this book and ebook
Published: August 2013
eBook Price: £8.99
See more
Select your format and quantity:

About the Author :


Simone Scarduzio

Simone Scarduzio is a backend software engineer at MPme, a mobile music startup based at the heart of "silicon roundabout" in London. His current quest is to make the MPme music search and recommendation engine as feature-rich and snappy as possible.

At MPme, it is a functional requirement for the core services to respond with a very low latency, regardless of the traffic. If this constraint were not respected, the system would send irrelevant recommendations to the clients. In terms of systems architecture, this means everything needs
to scale horizontally. That's why, any mobile client connecting to MPme, actually connects to a Vert.x application.

The use of Vert.x at MPme is massive and growing: reverse TCP proxies, Web radio monitors, and internal and external REST APIs are an example of this.

He has been involved in the Vert.x project since October 2012, as an early adopter. Countless development versions of Vert.x have crossed MPme servers in a continuous cycle of build, test, deploy, and feedback to the Vert.x team.

Before MPme, he lived for 3 years in Finland. Here, he cut his teeth as a software developer working on distributed mobile messages-processing systems at Mavenir, for customers such as Vodafone, Telefonica, Airtel, Idea, and T-Mobile.

The pleasure of discovery and exploration drives his relationship with all his main hobbies: technology, travelling, and food.

Books From Packt


Real-time Web Application Development with Vert.x
Real-time Web Application Development with Vert.x

Node Web Development
Node Web Development

Instant Node.js Starter [Instant]
Instant Node.js Starter [Instant]

CoffeeScript Programming with jQuery, Rails, and Node.js
CoffeeScript Programming with jQuery, Rails, and Node.js

Java EE 6 Development with NetBeans 7
Java EE 6 Development with NetBeans 7

Learning jQuery, Third Edition
Learning jQuery, Third Edition

Mastering Ext JS
Mastering Ext JS

Ext JS 4 First Look
Ext JS 4 First Look


Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software