Creating a Web Chat with Webix and WebSocket API

One of the latest cool APIs of the modern web is web sockets API. It allows creating real-time apps, where users can collaborate, get notifications and data updates whenever the data is changed. This article will show how you can create a simple web chat by using Webix and web sockets API.

webix-based-chat

Web chat is a “hello world” for real-time web apps. You can grab the final code from github.

Server side

We will use NodeJS platform, currently the best platform for real-time apps, as a server side. Assuming that you have NodeJS installed, let’s start with creating a new folder for the app and installing Faye library and Connect package. To install them you can run the next commands:

npm install faye
npm install connect

Faye is a publish-subscribe messaging system which can be used with NodeJS and Ruby on the server side. This system simplifies working with web sockets. “Connect” is a basic web-server for NodeJS.

Now let’s create our chat server. It will be just one file: server.js. The content of this file is very simple:

var connect = require('connect'),
faye = require('faye');

//serve static files
var app = connect()
.use( connect.static("public") )
.use( connect.logger('dev') ).listen(3000);

//init faye
var bayeux = new faye.NodeAdapter({mount: '/faye'});
bayeux.attach(app);

As you can see, we’ve created a web server at port 3000 which serves static files from the “public” folder. After that we’ve attached Faye adapter to the server. So much for the server code that we need.

WebSocket is an HTML API, so all the logic will be defined in the client-side code. Let’s start the web server and switch to the client-side code:

node server.js

Client side

First of all, let’s create a folder for the client-side files and call it “public”. Then we’ll add a file called “index.html” into it which contains the following code:

    <html>
<head>
   <title></title>
   <script type="text/javascript" src="http://cdn.webix.io/edge/webix.js"></script>
   <link rel="stylesheet" type="text/css" href="//cdn.webix.io/edge/webix.css">
</head>
<body>
<style type="text/css">
   .webix_list_item span{
       font-weight: bold;
       min-width: 100px;
       float: left;
       text-align: center;
   }
   .webix_list_item span.own{
       color:#4a4;
   }
</style>
<script type="text/javascript">
   var user_name = "Guest " + Math.ceil(Math.random()*9999);
   function chat_template(obj){
       return "<span "+(obj.user == user_name ? "class='own'" : "" )+">"+obj.user+"</span> "+obj.value;
   }
   function send_message(){
       var text = $$("message").getValue();

       if (text)
           $$("chat").add({
               user:  user_name,
               value: text
           });

       $$("message").setValue("");
       $$("message").focus();
   }

   webix.ui({
       rows:[
           { template:"Webix Based Chat", type:"header" },
           {
               view: "list", id:"chat", gravity:3,
               type:{ height:"auto" },
               template:chat_template
           },
           { cols: [
               { view:"text", id:"message", placeholder:"Type message here", gravity: 3},
               { view:"button", value: "Send", click:send_message }
           ]}
       ], type:"space", margin:2
   });

   webix.UIManager.addHotKey("Enter", send_message, $$("message"));
   webix.UIManager.setFocus($$("message"));
</script>

</body>
</html>

Well, let’s analyze what steps have been completed. We’ve loaded Webix library on the page and created a list of chat records and two controls below it for adding new records. After creating the list we’ve added a hotkey handler to the message box and moved focus to this input. You can open the page in a browser, type some text and hit the Enter key. Thus, a new message will be added to the list view. We haven’t used any web socket specific code so far, that is data in the app doesn’t go anywhere outside of the browser.

To enable web sockets the above code requires some adjustments:

    • we must add one more script tag to the head section in order to load the client side part of the Faye library
<script type="text/javascript" src="//localhost:3000/faye/client.js"></script>
    • we must init web socket transport protocol by adding the next code block to it before the creation of UI:
//init Faye
webix.proxy.faye.client = new Faye.Client('//localhost:3000/faye/');
//set unique client id
webix.proxy.faye.clientId = webix.uid();
    • in the configuration of the Webix list we must define the urls for data loading and data saving. As we are using web sockets, those will be not real urls but message channels.
{ view:"list", url:"faye->/data", save: "faye->/data"

This is it. If you open the page in a browser, you won’t see any changes. However, now you can open this page in different browsers. All the messages which you are writing in one browser window will be visible in the other window, and vice versa. It may sound not very impressive, but the code that we’ve created will work for any number of browsers and users anywhere in the world. For real world usage you will need to change the “localhost” in the code to the real host name.

Afterthoughts

As you can see, it isn’t very difficult to enable fast bidirectional communication in a browser. In order to sync the data of Webix component between multiple users you need just a few lines of code. The creation of a web chat is just an example, while the same technique can be used for more useful things like real-time data monitoring or multiuser collaboration.