Socket Io and Kubernetes

1/10/2022

I am trying to migrate a socket io service from GCP (App Engine) to a kubernetes cluster. Everything works fine on the GCP side (we have one instance of the server without replicas). The migration to k8s is going very well, except that when connecting the client socket to the server, it does not receive some information:

  • In transport 'polling': Of course, as there are two pods, this doesn't work properly anymore and the client socket keeps deconnecting / reconnecting in loop.

  • In 'websocket' transport: The connection is correctly established, the client can receive data from the server in 'broadcast to all client' mode => socket.emit('getDeviceList', os.hostname()) but, as soon as the server tries to send data only to the concerned client io.of(namespace).to(socket.id).emit('getDeviceList', JSON.stringify(obj)), this one doesn't receive anything...

  • Moreover, I modified my service to have only one pod for a test, the polling mode works correctly, but, I find myself in the same case as the websocket mode => I can't send an information to a precise client...

Of course, the same code on the App Engine side works correctly and the client receives everything correctly.

I'm working with:

"socket.io": "^3.1.0",
"socket.io-redis": "^5.2.0",
"vue": "^2.5.18",
"vue-socket.io": "3.0.7",

My server side configuration:

var io = require('socket.io')(server, {
  pingTimeout: 5000,
  pingInterval : 2000,
  cors: {
      origin: true, 
      methods: ["GET", "POST"],
      transports: ['websocket', 'polling'],
      credentials: true
  },
  allowEIO3: true
});
io.adapter(redis({ host: redis_host, port: redis_port }))

My front side configuration:

Vue.use(new VueSocketIO({
    debug: true,
    connection: 'path_to_the_socket_io/namespace,
    options: {
        query: `id=..._timestamp`,
        transports: ['polling']
    }
}));

My ingress side annotation:

kubernetes.io/ingress.class: nginx                               kubernetes.io/ingress.global-static-ip-name: ip-loadbalancer                                   
meta.helm.sh/release-name: xxx                                             
meta.helm.sh/release-namespace: xxx -release                                       nginx.ingress.kubernetes.io/affinity: cookie                     nginx.ingress.kubernetes.io/affinity-mode: persistent                   nginx.ingress.kubernetes.io/force-ssl-redirect: true                                                              nginx.ingress.kubernetes.io/proxy-connect-timeout: 10800  
nginx.ingress.kubernetes.io/proxy-read-timeout: 10800
nginx.ingress.kubernetes.io/proxy-send-timeout: 10800
nginx.org/websocket-services: app-sockets-cluster-ip-service 

My question is : why i can get broadcast to all user message and not specific message to my socket ?

Can someone try to help me ? :)

Thanks a lot !

-- Adrien DEBLOCK
google-app-engine
kubernetes
kubernetes-ingress
socket.io
vue.js

1 Answer

1/10/2022

I found the solution in the day.and share it.

In fact, the problem is not due to the kubernetes Cluster but due to the socket io and socket io redis adapter version.

I was using socket.io: 3.x.x and using socket.io-redis: 5.x.x In fact, i need to use the socket.io-redis: 6.x.x with this version of socket io :)

You can find the compatible version of socket io and redis adapter here: https://github.com/socketio/socket.io-redis-adapter#compatibility-table

Thanks a lot.

-- Adrien DEBLOCK
Source: StackOverflow