I have a Vue.js application that uses Socket.IO and am able to run it locally but not in a prod setup with S3 and a public socket server. The Vue.js dist/ build is on AWS S3 set up in a public website format. I have DNS and SSL provided by Cloudflare for the S3 bucket.
My socket.io server is running in a Kubernetes cluster that is created using KOPS on AWS. I have a network load balancer in front of it with the ingress being Nginx-ingress. I have added a few annotations as I have been debugging those are at the bottom of the annotations section below.
Error message:
WebSocket connection to '<URL>' failed: WebSocket is closed before the connection is established.
Issue: I am trying to get my front end to connect to the socket.io server to send messages back and forth. However, I can't due to the above error message. I am looking to figure out what is wrong that is causing this error message.
ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
# add an annotation indicating the issuer to use.
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt"
# needed to allow the front end to talk to the back end
nginx.ingress.kubernetes.io/cors-allow-origin: "https://app.domain.ca"
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-methods: "GET, PUT, POST, DELETE, PATCH, OPTIONS"
# needed for monitoring - maybe
prometheus.io/scrape: "true"
prometheus.io/port: "10254"
#for nginx ingress controller
ad.datadoghq.com/nginx-ingress-controller.check_names: '["nginx","nginx_ingress_controller"]'
ad.datadoghq.com/nginx-ingress-controller.init_configs: '[{},{}]'
ad.datadoghq.com/nginx-ingress-controller.instances: '[{"nginx_status_url": "http://%%host%%:18080/nginx_status"},{"prometheus_url": "http://%%host%%:10254/metrics"}]'
ad.datadoghq.com/nginx-ingress-controller.logs: '[{"service": "controller", "source":"nginx-ingress-controller"}]'
# Allow websockets to work
nginx.ingress.kubernetes.io/websocket-services: socketio
nginx.org/websocket-services: socketio
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
name: socketio-ingress
namespace: domain
spec:
rules:
- host: socket.domain.ca
http:
paths:
- backend:
serviceName: socketio
servicePort: 9000
path: /
tls:
- hosts:
- socket.domain.ca
secretName: socket-ingress-cert
socket io part of server.js
const server = http.createServer();
const io = require("socket.io")(server, {
cors: {
origin: config.CORS_SOCKET, // confirmed this is -- https://app.domain.ca -- via a console.log
},
adapter: require("socket.io-redis")({
pubClient: redisClient,
subClient: redisClient.duplicate(),
}),
});
vue.js main
const socket = io(process.env.VUE_APP_SOCKET_URL)
Vue.use(new VueSocketIO({
debug: true,
connection: socket,
vuex: {
store,
actionPrefix: "SOCKET_",
mutationPrefix: "SOCKET_"
}
})
);