build log: sentiment-chat pt3 | Implementing socket.io
Tags: websockets, socketio, node
Published: 2019-05-08 02:45:02

---
title: build log: sentiment-chat pt3 | Implementing socket.io
series: sentiment-chat
published: true
description: 
tags: websockets, socket.io, nodeJS
---

This is less about the overall project, and more about getting [socket.io](https://socket.io/) communicating from my client to the server. It's gonna be a very close-in, nose-to-the-grindstone type of deal.

Most of the guides that exist will tell you how to send and receive data, but aren't exactly clear on what goes where, so I'll be providing excessive code snippets as we walk through the project.

We're working with a Node/Express backend, and the setup for this is kind of particular. Here's what setting up socketio looks like on my server, with Express.

## **Server**

```javascript
const express = require('express');
const app = express();
const server = require ('http').createServer(app);
const io = require('socket.io')(server);
//...
server.listen(3000, ()=>{console.log('listening on 3000'})
```

The express/"app" setup works like any other Node/Express setup. However, it gets a little weirder on the next two lines. I'm not completely sure how they work, but it seems that we're creating some sort of http server, giving it our `app` as an argument, and creating some sort of a socketio connection, giving it `server` as an argument.

Instead of invoking `listen` as a method on our `app`, it's invoked on our `server`, which I'm assuming is what lets us take socket connections in addition to the rest of our normal server functionality.

I'm gonna assume that you know how to do the usual stuff. Serving routes and so on. So we'll skip that part. Instead, now that we've got the `io` thing, we'll listen for a connection.

```javascript
const express = require('express');
const app = express();
const server = require ('http').createServer(app);
const io = require('socket.io')(server);

io.on('connection', (socket)=>{
  console.log('user connected');
})

server.listen(3000, ()=>{console.log('listening on 3000'})
```

## **Client**

That's the server, for now. Let's have a look at the client.

In our `index.html`, we need to add the following tag: `<script src="/socket.io/socket.io.js"></script>`. This is, of course, a relative filepath. We don't set it up ourselves, but, rather, it's provided to us by using socket.io in our server.

With this script tag as a given, we can start doing stuff in our frontend to connect. Ignoring any other sort of frontend functionality, let's imagine we literally just have a javscript file that will connect to our server. It'd look like this:

```javascript
const socket = io()
```

`io` is provided to us by the script tag we inserted.

Now, when we launch our server and load our page in our browser, it'll trigger the `io.on('connection', ...)` listener and log `'user connected'` to our server's console.

Now that we've got a connection and have confirmed that the client and server are communicating, we'll need to listen for other events.

## **Server** (again)

So, let's get back to the server. We're listening for a connection, and firing off a callback once that connection is established.

```javascript
const express = require('express');
const app = express();
const server = require ('http').createServer(app);
const io = require('socket.io')(server);

io.on('connection', (socket)=>{
  console.log('user connected');
})

server.listen(3000, ()=>{console.log('listening on 3000'})
```

What tripped me up is that I thought we could just add another `io.on`, similar to the event listener for `'connection'`. However, we actually need to add other event listeners inside of the callback for our `io.on('connection')`. 

You may have noticed that we're taking a parameter called `socket` inside of our callback. That will actually provide us with an object with an `on` method on it, which we'll use to create another event listener. We can name our listener anything we want. We'll call it `'hello'`.

```javascript
const express = require('express');
const app = express();
const server = require ('http').createServer(app);
const io = require('socket.io')(server);

io.on('connection', (socket)=>{
  console.log('user connected');
  socket.on('hello', (data)=>{
    console.log('data received:', data)
  }
})

server.listen(3000, ()=>{console.log('listening on 3000'})
```
similar to the `io.on`, `socket.on` takes two arguments. The first is a a string that corresponds to an event to listen for. The second is a callback function. In this case, we expect the callback to get some data that we'll send from our frontend.

Now, let's get back to the frontend.

## **frontend** (again)

Here's where we left off. `io` opens up a connection to our backend, which lives on the `socket` object.

```javascript
const socket = io();
```

Let's do a little hello world. Sending data from the frontend is fairly easy. Now that we have `socket`, we can just do this:

```javascript
const socket = io();

socket.emit('hello', 'hi from the frontend!');
```

The first argument of `socket.emit` is, of course, the name of the event. Our backend is listening for a `'hello'`, so our frontend is sending out that `'hello'`. The second argument is data that we're sending out, corresponding to the event.

## **Tying it all together**

So, when our frontend fires

```javascript
socket.emit('hello', 'hi from the frontend!');
```

our backend catches it here:

```javascript
io.on('connection', (socket)=>{
  console.log('user connected');
  socket.on('hello', (data)=>{
    console.log('data received:', data)
  }
}
```

Our server receives the `'hello'` event, and takes `'hi from the frontend'` as `data` in our callback function, and, finally, logs `data received: 'hi from the frontend'` to the console.

With this, we can send messages from our client to the server. Next, we'll need to have our clients listen for messages from the server. I'm hoping to get that done tomorrow, then spend the rest of the week doing UI/UX stuff. Thanks for reading along!