1

I create a server and bind socket.io on it

const express = require('express');
var io = require('socket.io');
var app = express();
app.get('/', (req, res) => {
   res.sendFile(__dirname + '/index.html');
})
var server = require('http').createServer(app);

io = io.listen(server);


io.on('connection', function(socket){
    console.log('user connected', socket.id)
    socket.on('chat message', function(msg){
    console.log(socket.id, 'message: ' + msg);
   });
});

server.listen(9999)

it's ok when I deploy 1 instance on docker (I use docker swarm and docker stack), while if I set the deploy replicas

this's my compose.yml

version: '3'
services:
  web:
  image: socket:v2
  ports:
    - "5000:9999"
    command: node index.js
    deploy:
    replicas: 2

I meet some problems, when send message to server, server1 show connected, and show got messages, but next time I send, server2 show got messages

How can I make it to be 'which server I connected is which server I send messages to'?

karl
  • 57
  • 8
  • 1
    I think you need to apply and configure Sticky sessions, you can read this https://stackoverflow.com/questions/10494431/sticky-and-non-sticky-sessions – LinPy Aug 20 '19 at 06:11

1 Answers1

3

you can use jwilder/nginx-proxy. which is an Automated Nginx proxy for Docker containers using docker-gen.

Usage

To run it:

$ docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy

Then start any containers you want proxied with an env var VIRTUAL_HOST=subdomain.youdomain.com

$ docker run -e VIRTUAL_HOST=foo.bar.com 

The containers being proxied must expose the port to be proxied, either by using the EXPOSE directive in their Dockerfile or by using the --expose flag to docker run or docker create.

Provided your DNS is setup to forward foo.bar.com to the host running nginx-proxy, the request will be routed to a container with the VIRTUAL_HOST env var set.

With Docker-compose you can try this example

Docker Compose

version: '2'

services:
  nginx-proxy:
    image: jwilder/nginx-proxy
    ports:
      - "80:80"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro

  whoami:
    image: jwilder/whoami
    environment:
      - VIRTUAL_HOST=whoami.local

Here jwilder/whoami will be proxied by jwilder/nginx-proxy as its specified VIRTUAL_HOST

You can read more about jwilder/nginx-proxy here and here

Also, you can check this docker-compose-scale-with-sticky-sessions

You can check the above example

docker-compose up

Then run

curl -H "Host: whoami.local" localhost

You will see one container ID in every response

Now, its time to scale

docker-compose scale whoami=3

Now see the screenshot response from a different container.

enter image description here

To work with the sticky session you can use tpcwang's fork allows you to use the IP_HASH directive on a container level to enable sticky sessions.

If you are interested in built-in feature then you can try Implement persistent (sticky) sessions

You can publish a service and configure the proxy for persistent (sticky) sessions using:

  • Cookies
  • IP hashing

IP Hashing

The following example shows how to configure sticky sessions using client IP hashing. This is not as flexible or consistent as cookies but enables workarounds for some applications that cannot use the other method. When using IP hashing, reconfigure Interlock proxy to use host mode networking, because the default ingress networking mode uses SNAT, which obscures client IP addresses.

Create an overlay network so that service traffic is isolated and secure:

$> docker network create -d overlay demo

Create a service with the cookie to use for sticky sessions using IP hashing:

$> docker service create \
    --name demo \
    --network demo \
    --detach=false \
    --replicas=5 \
    --label com.docker.lb.hosts=demo.local \
    --label com.docker.lb.port=8080 \
    --label com.docker.lb.ip_hash=true \
    --env METADATA="demo-sticky" \
    ehazlett/docker-demo

Interlock detects when the service is available and publishes it. When tasks are running and the proxy service is updated, the application is available via http://demo.local and is configured to use sticky sessions:

Adiii
  • 54,482
  • 7
  • 145
  • 148