Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
196 views
in Technique[技术] by (71.8m points)

node.js - Websocket behind apache - Unexpected response code 500

I have a NodeJS api with a websocket using socket.io. The api listen on http://localhost:8080 and ws://localhost:8080.

Server side (NodeJS, "socket.io": "2"):

  // SOCKET_ORIGINS="*"
  let io = require('socket.io')(server, {    
    origins: "*",
  })

  // AUTH_SECRET="asecret"
  io.use(socketioJwt.authorize({
    secret: AUTH_SECRET,
    handshake: true
  }))

  io.on('connection', (socket) => {
    console.log('a user connected', socket.id, socket.decoded_token.user_id);  
    
    io.users.push({user_id:socket.decoded_token.user_id, sid:socket.id})

    socket.on('disconnect', () => {
      console.log('user disconnected'); 
    }); 
  });

Client side (Angular 10, "socket.io-client": "^2.2.0"):

      let token = JSON.parse(localStorage.getItem('token'))

      // connect 
      this.socket = socketIo.connect(this.globalServices.socketURL,{ transports: ['websocket'],
        query: 'token='+ token});
      
      // authentication handler
      this.socket.on('connect', () => {
        console.debug("socket connected", this.socket.id)                
      })

Everything works like a charm locally. I'm able to request both, http and ws without any issue. Then, I'm deploying my api on a server (configuration: Debian 8.11, Apache 2.4, npm 3.10.10). Apache configuration:

<VirtualHost *:443>
  ProxyPreserveHost On
  ServerName my-api.net
  ServerAdmin admin@my-api.com
  DocumentRoot /opt/my-api/api/versions/default/public

  RewriteEngine on
  RewriteCond %{HTTP:UPGRADE} ^websocket$ [NC]
  RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
  RewriteRule /(.*)$ ws://127.0.0.1:3080/$1 [P,L]

  ProxyRequests off
  ProxyPass /socket.io/ ws://127.0.0.1:3080/socket.io/
  ProxyPassReverse /socket.io/ ws://127.0.0.1:3080/socket.io/

  ProxyPass / http://127.0.0.1:3080/ retry=0 timeout=5
  ProxyPassReverse / http://127.0.0.1:3080/

  SSLEngine On
  KeepAlive On
  SSLCipherSuite          ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
  SSLHonorCipherOrder     on
  SSLOptions +StrictRequire

  SSLCertificateFile /etc/letsencrypt/live/my-api.net/fullchain.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/my-api.net/privkey.pem

  ErrorLog /opt/my-api/logs/apache-my-api-error.log
  CustomLog /opt/my-api/logs/apache-my-api-access.log combined

</VirtualHost>

The api is on port 3080 on the server and it runs.

$ lsof -i -P -n | grep '3080'
node      50041     lgrenier   23u  IPv6 124610904      0t0  TCP *:3080 (LISTEN)

Also, pm2 status is ok:

┌─────┬───────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id  │ name      │ namespace   │ version │ mode    │ pid      │ uptime │ ?    │ status    │ cpu      │ mem      │ user     │ watching │
├─────┼───────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 4   │ my-api    │ default     │ 0.0.1   │ fork    │ 50041    │ 83m    │ 28   │ online    │ 0.4%     │ 70.2mb   │ lgrenier │ disabled │
└─────┴───────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘

The api start without any error.

All my HTTPS requests work but the WSS doesn't. They fail with the following error message on the client side

main-es2015.ce216019692753660ec5.js:1 WebSocket connection to 'wss://my-api.net/socket.io/?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHBpcmVzSW4iOjI1OTIwMDB9.eFYbyoZ6a53Sf72iX5mjgRWrIij2tWYl_PQnOVlCKPY&EIO=3&transport=websocket' failed: Error during WebSocket handshake: Unexpected response code: 500

Despite the error message, there isn't any trace of my call in Apache logs or pm2 logs. Where am I wrong ?

question from:https://stackoverflow.com/questions/66060427/websocket-behind-apache-unexpected-response-code-500

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

On the server side, the cors aren't correctly set:

Wrong CORS settings

  // SOCKET_ORIGINS="*"
  let io = require('socket.io')(server, {    
    origins: "*",
  })

Right CORS settings

  // SOCKET_ORIGINS="*"
  let io = require('socket.io')(server, {    
    cors:{ origin: "*" }
    })

As simple as that.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...