Skip to content

Commit 86eb422

Browse files
docs(examples): add example with traefik
Reference: https://doc.traefik.io/traefik/v2.0/
1 parent cf873fd commit 86eb422

File tree

9 files changed

+637
-0
lines changed

9 files changed

+637
-0
lines changed

examples/cluster-traefik/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
# Socket.IO Chat with traefik & [redis](https://redis.io/)
3+
4+
A simple chat demo for Socket.IO
5+
6+
## How to use
7+
8+
Install [Docker Compose](https://docs.docker.com/compose/install/), then:
9+
10+
```
11+
$ docker-compose up -d
12+
```
13+
14+
And then point your browser to `http://localhost:3000`.
15+
16+
You can then scale the server to multiple instances:
17+
18+
```
19+
$ docker-compose up -d --scale=server=7
20+
```
21+
22+
The session stickiness, which is [required](https://socket.io/docs/v3/using-multiple-nodes/) when using multiple Socket.IO server instances, is achieved with a cookie. More information [here](https://doc.traefik.io/traefik/v2.0/routing/services/#sticky-sessions).
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
version: "3"
2+
3+
services:
4+
traefik:
5+
image: traefik:2.4
6+
volumes:
7+
- ./traefik.yml:/etc/traefik/traefik.yml
8+
- /var/run/docker.sock:/var/run/docker.sock
9+
links:
10+
- server
11+
ports:
12+
- "3000:80"
13+
- "8080:8080"
14+
15+
server:
16+
build: ./server
17+
links:
18+
- redis
19+
labels:
20+
- "traefik.http.routers.chat.rule=PathPrefix(`/`)"
21+
- traefik.http.services.chat.loadBalancer.sticky.cookie.name=server_id
22+
- traefik.http.services.chat.loadBalancer.sticky.cookie.httpOnly=true
23+
24+
redis:
25+
image: redis:6-alpine
26+
labels:
27+
- traefik.enable=false
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
FROM node:14-alpine
2+
3+
# Create app directory
4+
RUN mkdir -p /usr/src/app
5+
WORKDIR /usr/src/app
6+
7+
# Install app dependencies
8+
COPY package.json /usr/src/app/
9+
RUN npm install --prod
10+
11+
# Bundle app source
12+
COPY . /usr/src/app
13+
14+
EXPOSE 3000
15+
CMD [ "npm", "start" ]
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Setup basic express server
2+
var express = require('express');
3+
var app = express();
4+
var server = require('http').createServer(app);
5+
var io = require('socket.io')(server);
6+
var redis = require('socket.io-redis');
7+
var port = process.env.PORT || 3000;
8+
var crypto = require('crypto');
9+
var serverName = crypto.randomBytes(3).toString('hex');
10+
11+
io.adapter(redis({ host: 'redis', port: 6379 }));
12+
13+
server.listen(port, function () {
14+
console.log('Server listening at port %d', port);
15+
console.log('Hello, I\'m %s, how can I help?', serverName);
16+
});
17+
18+
// Routing
19+
app.use(express.static(__dirname + '/public'));
20+
21+
// Chatroom
22+
23+
var numUsers = 0;
24+
25+
io.on('connection', function (socket) {
26+
socket.emit('my-name-is', serverName);
27+
28+
var addedUser = false;
29+
30+
// when the client emits 'new message', this listens and executes
31+
socket.on('new message', function (data) {
32+
// we tell the client to execute 'new message'
33+
socket.broadcast.emit('new message', {
34+
username: socket.username,
35+
message: data
36+
});
37+
});
38+
39+
// when the client emits 'add user', this listens and executes
40+
socket.on('add user', function (username) {
41+
if (addedUser) return;
42+
43+
// we store the username in the socket session for this client
44+
socket.username = username;
45+
++numUsers;
46+
addedUser = true;
47+
socket.emit('login', {
48+
numUsers: numUsers
49+
});
50+
// echo globally (all clients) that a person has connected
51+
socket.broadcast.emit('user joined', {
52+
username: socket.username,
53+
numUsers: numUsers
54+
});
55+
});
56+
57+
// when the client emits 'typing', we broadcast it to others
58+
socket.on('typing', function () {
59+
socket.broadcast.emit('typing', {
60+
username: socket.username
61+
});
62+
});
63+
64+
// when the client emits 'stop typing', we broadcast it to others
65+
socket.on('stop typing', function () {
66+
socket.broadcast.emit('stop typing', {
67+
username: socket.username
68+
});
69+
});
70+
71+
// when the user disconnects.. perform this
72+
socket.on('disconnect', function () {
73+
if (addedUser) {
74+
--numUsers;
75+
76+
// echo globally that this client has left
77+
socket.broadcast.emit('user left', {
78+
username: socket.username,
79+
numUsers: numUsers
80+
});
81+
}
82+
});
83+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "socket.io-chat",
3+
"version": "0.0.0",
4+
"description": "A simple chat client using socket.io",
5+
"main": "index.js",
6+
"author": "Grant Timmerman",
7+
"private": true,
8+
"license": "MIT",
9+
"dependencies": {
10+
"express": "4.13.4",
11+
"socket.io": "^3.1.0",
12+
"socket.io-redis": "^6.0.1"
13+
},
14+
"scripts": {
15+
"start": "node index.js"
16+
}
17+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Socket.IO Chat Example</title>
6+
<link rel="stylesheet" href="style.css">
7+
</head>
8+
<body>
9+
<ul class="pages">
10+
<li class="chat page">
11+
<div class="chatArea">
12+
<ul class="messages"></ul>
13+
</div>
14+
<input class="inputMessage" placeholder="Type here..."/>
15+
</li>
16+
<li class="login page">
17+
<div class="form">
18+
<h3 class="title">What's your nickname?</h3>
19+
<input class="usernameInput" type="text" maxlength="14" />
20+
</div>
21+
</li>
22+
</ul>
23+
24+
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
25+
<script src="/socket.io/socket.io.js"></script>
26+
<script src="/main.js"></script>
27+
</body>
28+
</html>

0 commit comments

Comments
 (0)