hapi-socketio-redis-chat-example

:speech_balloon: Real-time Chat using Hapi.js + Socket.io + Redis Pub/Sub (example with tests!!)

Github stars Tracking Chart

Hapi.js Socket.io Redis Chat Example

Build Status
Test Coverage by codecov.io
Code Climate
Dependency Status
devDependency Status

A basic chat application built with Hapi.js Socket.io and Redis Publish/Subscribe

Try it: https://hapi-chat.herokuapp.com/

hapi-chat-screenshot

Why?

Node.js Chat Apps are practically the "Hello World" of real-time apps.
If you Google for
"node.js chat example"
you will see thousands of results! But ... 90% of the examples use Express.js,
95% use MongoDB to store data/messages and 100% have zero tests.
So, this example is for the the people who prefer to have examples
that are fully explained (including tests).

As with all our examples we have a suite of tests.

What?

Real-Time
Chat is an integral part of any communications system.
Building a (basic) chat system is easy with Socket.io.

This example app shows you how to use Socket.io with Hapi.js and Redis for a
Horizontally Scalable
chat capable of hundrededs of thousands of concurrent clients.

How?

We are using the following components to build our chat app:

  1. Hapi.js (node.js web framework) - If you haven't used Hapi.js before,
    checkout our introductory tutorial: https://github.com/dwyl/learn-hapi

Why Redis?

Socket.io only handles distributing messages, if people disconnect
from the chat they will miss any subsequent messages and
when anyone connects there will see no history ...
so we need a place to store messages for retrieval.

Top 3 reasons why Redis is the clear choice for storing chat messages.

  1. Speed - Redis is much faster than MongoDB,
    CouchDB or PostgreSQL
  2. Simple - pushing messages onto a list (set) is the simplest
    possible
    way to store a chat history. Given that we can store up to
    512Mb per chat and stream chat history to new clients
    (low http overhead) its an incredibly simple setup!
  3. Scalable Publish/Subscribe ("pattern") means we can scale out
    (add more node.js/socket.io servers when you need to serve more clients)
    Redis can already handle an order of magnitude more than
    other NoSQL Databases, so your most likely "bottleneck" is node (nuts, hey!?)

Publish / Subscribe ...?

The Publish Subscribe "Pattern" is (still) the simple_st_
way of scaling software applications. If you are new to this idea,
see: https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern

Mobile First

Given the simplicity of the UI, the chat app is mobile-first by default.

If anyone has time to Pull Request a few CSS media
queries to make the UI even better on mobile devices,
we would massively appreciate the contribution
!

Returning Visitor

We use cookies to store the person's name on the client. If the person
clears cookies (or uses private browsing / incognito mode) they will be asked
for their name each time they open the chat window. (this is pretty standard).

 How Many Recent Messages Should we Cache?

At present we are caching all the messages in Redis.
But a less RAM-hungry way to scale the app would be to store only
the 50-100 most recent chat messages in Redis (RAM) and the remaining
history in a cheaper on-disk storage e.g. ElasticSearch
(which would also enable searchability)

Data Model

Data Model we have used is incredibly simple.
It translates to an array of objects:

var chat =  [
  '{"m":"Hi everyone!","t":1436263590869,"n":"Steve"}',
    '{"m":"Hi Steve! Welcome to Hapi Chat!","t":1436263599489,"n":"Foxy"}',
    '{"m":"Hapi Chat lets you chat with your friends!","t":1436263613141,"n":"Oprah"}',
    '{"m":"Cool! How does it scale?","t":1436263620853,"n":"Steve"}',
    '{"m":"Funny you should ask! It scales nicely because it uses Hapi.js and Redis!","t":1436263639989,"n":"Chroma"}',
    '{"m":"Sweet! ","t":1436263645610,"n":"Steve"}',
    '{"m":"Hello","t":1436264664835,"n":"Timmy"}',
    '{"m":"Hi!","t":1436267152379,"n":"Timmy"}',
    '{"m":"lkjlkjlk","t":1436270948402,"n":"dd"}',
    '{"m":"Big fan of the little notifications at the top when a person joins","t":1436273109909,"n":"iteles"}'
]

We use single letters for field keys:

  • m for message.
  • n for name of the person who wrote the message
  • t for timestamp the message was received by the
    node server (to avoid time-zone issues);

Run it! (it's easy!)

Locally (on your own machine)

Try running the app! (Its as easy as 1, 2, 3!)

1. Clone the Repository

git clone https://github.com/dwyl/hapi-socketio-redis-chat-example.git
cd hapi-socketio-redis-chat-example

2. Install Redis (if you don't already have it!)

If you haven't already got an instance of Redis running on your machine,
Our Redis tutorial has instructions:

https://github.com/dwyl/learn-redis#installation

3. Install the Dependencies and Start the Server

Install the dependencies and start the app with:

npm install && npm start

Now visit: http://127.0.0.1:8000 (in your browser)

Running the Tests (Locally)

To successfully run the tests you need to have an environment variable
for RedisCloud (this is because we like to know that our code works
on both "local" and in a "production" environment...)

E.g:

export REDISCLOUD_URL=redis://rediscloud:yourpassword@pub-redis-12345.eu-west-1-2.1.ec2.garantiadata.com:12345

Given that our tests include checks for RedisCloud, you will need to have
internet access to run them ...

Running the Elm version

At dwyl we really like Elm
and Tachyons
and they're part of our
core technology stack,
so as well as the standard Javascript/HTML/CSS front end we've made one
in Elm so you can see what goes into a chat app in Elm as well.

You'll need
Elm installed on your machine
to run it so make sure you have that.

If you've never done Elm before we recommend starting with our
learn-elm-architecture
tutorial, and then moving onto learn-elm,
and once you're done with them come here and check out how the chat app works!

To run the Elm version go into your terminal and run:

npm run start-elm

this script runs elm-make when it runs, so will prompt you to install all
of the elm-stuff when you first run it, then go to localhost:8000/elm
(make sure you're not running the server already!).

If you're interested in the code go into elm/src/Main.elm,
it's commented all the way through so that you can understand everything.
(if anything is unclear,
let us know!)

We also have tests!

npm run test-elm

Elm doesn't currently have a coverage tool but we try to make sure all
of our logic is tested. If you haven't tested your Elm code before,
start now!

Heroku (deploying to Heroku)

Are you new to deploying apps to Heroku?
(Message us we can talk/walk you through it...!)

Background Reading

HitCount

Main metrics

Overview
Name With Ownerdwyl/hapi-socketio-redis-chat-example
Primary LanguageElm
Program languageHTML (Language Count: 4)
Platform
License:GNU General Public License v2.0
所有者活动
Created At2015-07-06 08:27:31
Pushed At2017-07-14 15:50:32
Last Commit At2017-07-14 16:47:52
Release Count0
用户参与
Stargazers Count361
Watchers Count36
Fork Count73
Commits Count183
Has Issues Enabled
Issues Count70
Issue Open Count28
Pull Requests Count34
Pull Requests Open Count0
Pull Requests Close Count2
项目设置
Has Wiki Enabled
Is Archived
Is Fork
Is Locked
Is Mirror
Is Private