18
Jun

Local Websocket server and UI Implementation

Websockets are easy – both conceptually and in their implementation. This tutorial aims to provide some basic information about websockets and an easy to follow example that even a programming novice could understand.

Websockets simply connect a browser(client) to a server, and allow for data to be passed back and forth between them. The websocket connection remains open until either the client or the server closes the connection. Here are some benefits for using websockets instead of REST/HTTP:

1. Websocket connections stay open – HTTP connections do not. With HTTP, a message is sent to the server, a connection is opened, the message is processed on the server, the connection is closed. This adds a huge amount of unwanted overhead when frequently sending a lot of data.

2. The server cannot send data to the client without the client requesting it. Websockets make it possible for the server to send data to the client(browser) whenever it likes.

That’s as much as any novice needs to understand. Please, do some of your own research, there’s plenty of infomation out there.

The example will allow you to see how websocket interactions would work between a client and a server. This will all be done locally on your own computer (perfect for novices, eh!), and will be a simple demonstation of a (local) client/browser and (local) server sending data back and forth to each other.

First lets start with our client:

1. Create a folder called “websocket-browser-ui”.
2. Inside that folder, create a file “index.html” and paste the following code:

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <input id="text-field" type="text" /> 
    <button id="submit-btn">SUBMIT</button> 
    <button id="connect-server-btn">CONNECT TO SERVER</button>
    <ul id="submission-list"></ul>
    <script src="index.js"></script>
  </body>
</html>

3. Inside the same folder create a file “index.js”. We’ll populate the code in this file later.

Next lets work on the server. Our local server will need to host a websocket server that will sit and wait for clients (browsers) to connect to it. Of course, for our server we’ll use node.js. For our websocket server, we’ll use the node package ‘ws’. Here’s a link to the package page. ‘ws’ is very simple to use, and it has a websocket server ready to go, with only a single line of instantiating code.

Our server code:

1. Install node.js.
2. Create a folder called “websocket-server”.
3. Navigate into the folder via a Terminal of your choice, and initialise an npm project by running:

npm init

4. Press enter through all the steps.
5. Install the ‘ws’ package by running:

npm install ws --save

You now have an npm project set up, and ws installed in it.

6. In this same folder create a file called “websocket-server.js” and paste the following code:

  
var WebSocketServer = require('ws').Server
var wss = new WebSocketServer({ port: 8888 })

console.log('NODE SERVER IS RUNNING')

7. In terminal run the command:

node websocket-server.js

Now you have a websocket server running and listening at “ws://localhost:8888” – if you look at the terminal you will see ‘NODE SERVER IS RUNNING’ has been logged. Great! But we now have a problem… We have a websocket server running, but it doesn’t know what to do when a browser connects and sends data/messages to it!

So we now need to write some functions to deal with when a client initiates a websocket connection, and when a client sends data/messages to the server via this websocket connection:

8. Under the three previous lines of code let’s write the following:

  
wss.on('connection', function connection(ws) {
  console.log('Socket connected after connection handshake was initiated by the client/browser')
  ws.send('The server and client are now connected via a websocket!')

  ws.on('message', function incoming(message) {
    console.log('Server received: %s', message);
    ws.send('The server just received a message from the client/browser')
  })
})

The previous code is very simple. When a ‘connection’ between the client and server is made, a message is console.logged on the server and a message is instantly sent to the client/browser (via ws.send(‘The server and client are now connected via a websocket!’)). Then when a ‘message’ is received from the client/browser, this message is also console.logged on the server, and a separate message is instantly sent back to the client (via ws.send(‘The server just received a message from the client/browser’)).

That’s it. We record when the websocket connection is made, and we record when the client/browser sends the server a message. Very simple.

Currently we have a working websocket server – great, but the browser has no idea how to socket to the server, or how to send messages to it.

So now we need to finish the client/browser code. We won’t use ‘ws’ for the browser because there is a vanilla javascript Websocket object that can be used. ‘ws’ was used for the websocket server.

9. Open index.js in the websocket-browser-ui project and write the following code:

  
var input = document.getElementById("text-field")
var submitButton = document.getElementById("submit-btn")
var connectButton = document.getElementById("connect-server-btn")
var ul = document.getElementById("submission-list")
var ws
  
connectButton.onclick = () => {
  //this connects to our locally running websocket server
  ws = new WebSocket('ws://localhost:8888')

  ws.onopen = () => {
    ws.send('Client now connected to server')
  }

  ws.onmessage = (message) => {
    var li = document.createElement("li");
    li.appendChild(document.createTextNode('SERVER SENT: ' + message.data));
    return ul.appendChild(li)
  }
}

submitButton.onclick = () => {
  ws.send(input.value)
  var li = document.createElement("li");
  li.appendChild(document.createTextNode('BROWSER SENT: ' + input.value));
  return ul.appendChild(li)
}

And that’s all of the browser code sorted! Initially we create variables for each of the elements in our ui and then move onto the functions that make them usable.

– The first function “connectButton.onclick” connects us to our locally running websocket server. Notice the url is the same as the websocket server’s: “ws://localhost:8888”. Within this function, we then write the code for two functions for how to handle when the websocket connects and when a message is received:
– The second function “ws.onopen” sends a message to the websocket server when a websocket connection has been made between the browser/client and the server. So essentially, after the connectButton has been clicked and the websocket connection has been made, this message will be sent.
– The third function “ws.onmessage” decides what to do when the browser receives a message from the server. In our case we add the message to a list in the ui.
– The fourth function “submitButton.onclick” sends whatever value has been typed into the text box to the websocket server AND prints the sent message to the screen.

Now, let’s test it!

First lets run the websocket server. Navigate into the websocket-server folder via your terminal and run the command:

node websocket-server.js

Again, you’ll see the “NODE SERVER IS RUNNING” message in your terminal.

Now let’s open our client/browser ui by going into the websocket-browser-ui folder, and opening the index.html file in your browser. Click the ‘CONNECT TO SERVER’ button, and you should see the connection message sent from the server on screen AND the connection message you sent to the server on screen! Have a look at your terminal and you’ll see the connection message sent from the browser to the server too!

Now type a message into the text input box and press the ‘SUBMIT’ button – you will see that on screen, and if you look at your terminal again, you’ll see your sent message is logged their also!

Voila! We now have a local websocket server and a local ui, both sending and receiving messages from each other.