Blog

Creating a Web Chat with Webix and WebSocket API

January 29, 2014

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="http://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-&gt;/data", save: "faye-&gt;/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.

Written by
The following two tabs change content below.

Maksim Kozhukh

Pragmatic software developer with more than 12 years of web development experience. Prefers to work with Javascript and HTML. Maksim has worked with lots of different technologies from nearly forgotten ColdFustion to the bleeding edge of NodeJS and Go.
Share on Google Plus Share on Twitter Share on Facebook Share on Stumbleupon Share on LinkedIn Bookmark on del.icio.us Vote on Reddit
  • dRaul

    HI, is there some equivalent or future implementation like “Live update (DHTMLX)”?

    knowing that implement state node with websockets, so the question

    I’m interested to know if there is any implementation for socket.io like faye :)

    • Maksim Kozhukh

      There is no ready to use implementation of socket.io, but it can be done in similar way.
      You can check webix.proxy.faye in the code of webix_debug.js and add the similar proxy for socket.io or any other data provider.