So what are WebSockets? A WebSocket is a protocol that allows communication over TCP in web browsers and web servers. In most instances you have a server and a client and they communicate with each other over a socket.

You might remember I created a basic Socket.IO tutorial using Express and Node in a previous post. It was really easy to setup and work with. Today I'll be looking into using the latest ember-websockets addon by Travis Hoover.

Unfortunately the addon doesn't work with Socket.IO so we'll be using another web socket library called ws. It works almost the same way as Socket.IO.

Getting Started On Node

We aren't going to get into too much detail on setting up the Node server. We are essentially just seeing if we can get communication going.

First let's create an empty Node project.

$ mkdir WebSocketNode
$ cd WebSocketNode
$ npm init //fill out responses
$ npm install --save ws

The npm init will create a package.json file. 'ws' is the node web socket package we'll be using for this tutorial.

We want to see if we can create a really basic web service. We'll create a server.js file with just the basics in it.

// server.js

var WebSocketServer = require('ws').Server;
var ws = new WebSocketServer({port: 7000});


ws.on('connection', function connection(ws) {
  ws.on('message', function incoming(message) {
    console.log('received: %s', message);
  });

  ws.send('Hey! Welcome to my websocket challenge!');
});

All this does is is send a welcome message as soon as some one connects and logs to the console whenever it receives a message. Simple right? Let's start it

$ node server.js

Ember Setup

To begin we'll create a new project and install the websockets addon.

$ ember new embersockets
$ cd embersockets
$ ember g route chat --pod //pod style
$ ember install ember-websockets 
$ ember g initializer websocket

After everything is installed we'll need to do our usual CSP cleanup so that way Ember can talk to our web socket Node server.

// config/environment.js
...
APP: {
...
},
           contentSecurityPolicy: {
              'default-src': "'none'",
              'script-src': "'self' 'unsafe-inline' 'unsafe-eval'",
              'font-src': "'self'",
              'connect-src': "'self' ws://localhost:7000 localhost:7000",
              'img-src': "'self'",
              'report-uri':"'localhost'",
              'style-src': "'self' 'unsafe-inline'",
              'frame-src': "'none'"
            }

Now we won't get any unusual errors in the console or have issues connecting. The EmberJS WebSockets Addon is a service. So for us to use it we'll need to inject it into all our controllers. Earlier I generated an initializer. We'll go ahead and use that to inject the websocket service.

// initializer/websocket.js

export function initialize(/* container, application */) {
  // application.inject('route', 'foo', 'service:foo');
}

export default {
  name: 'websockets',
  initialize: function(container, app) {
        app.inject('controller', 'websockets', 'service:websockets');
  }
};

Since there is already a service called 'websockets' we don't have to register it.

Next up is our controller. For this demo we just want to see if we can send a message to the server, and display a message from the server.

// app/chat/controller.js
import Ember from 'ember';

export default Ember.Controller.extend({

  init: function() {
    this._super();
    var socket = this.get('websockets').socketFor('ws://localhost:7000/');
    socket.on('open', this.myOpenHandler, this);
    socket.on('message', this.myMessageHandler, this);
    socket.on('close', function(event) {
        console.log('closed');
    }, this);
  },
  message: '',

  myOpenHandler: function(event) {
    console.log('On open event has been called: ' + event);
  },

  myMessageHandler: function(event) {
    console.log('Message: ' + event.data);
    this.set('message',event.data);
  },

  actions: {
    sendButtonPressed: function() {
      var socket = this.get('websockets').socketFor('ws://localhost:7000/');
      socket.send('Hello Websocket World');
    }
  }
});

Here the controller init function is setting up the message and open handlers. It's worth noting this.get('websockets') is the injected service. We now can update the template.

// app/chat/template.hbs
Welcome Chat!<br><br>

Received Message: {{message}}<br>
<button id="sendButtonPressed" {{action "sendButtonPressed"}}>Press Me</button>

This is really simple. We are displaying the message after receiving it from the socket server. We'll send an action when the button is pressed. That action will send a message to the server.

Testing It Out

That should be it on the Ember and Node side. We can test it out by making sure both our Ember and Node servers are running.

$ ember s
$ node server.js //if not already running

After we load up our Ember server at 'http://localhost:4200/chat' we should see a message from our Node server and if we look at the chrome console we'll see the message printed out there as well.

We can now press the button and we should see this on our Node server console window.

$ received: Hello Websocket World

Hooray! It works!

Future

In a future post we'll try to create a fully functional chat server. This post was just to see if I could get it working. Thanks for stopping by!

Questions? Tweet me at @ErikCH.

Image Credit Legrand.com.sg/

Getting Started With WebSockets And Ember