简体   繁体   中英

Socket.io and Node.js not working on Heroku

So I'm building a simple chat-room app using socket.io, and it works fine on my localhost.

The problem comes when I deploy it to Heroku: then sockets.io no longer works.

I looked at similar questions on the forum and tried different solutions, but I wasn't able to solve the problem. Could you help me?

These are my heroku logs from my latest build, and they don't even show the console.log()'s I set in the program for when a message is sent (I don't know whether it's normal or not):

2017-02-13T18:09:43.330870+00:00 app[web.1]: > node server.js
2017-02-13T18:09:43.330870+00:00 app[web.1]:
2017-02-13T18:09:43.996962+00:00 heroku[web.1]: State changed from starting to up
2017-02-13T18:09:43.959778+00:00 app[web.1]: Option match origin protocol is not valid. Please refer to the README.
2017-02-13T18:09:43.967627+00:00 app[web.1]: Server running on port 17411
2017-02-13T18:09:59.643406+00:00 heroku[router]: at=info method=GET path="/chat/" host=gagliachat.herokuapp.com request_id=e2c5a
44f-0e95-4bbb-b3be-77140713a355 fwd="93.65.75.16" dyno=web.1 connect=1ms service=104ms status=200 bytes=1413
2017-02-13T18:09:59.771747+00:00 heroku[router]: at=info method=GET path="/chat/index.js" host=gagliachat.herokuapp.com request_
id=e11067f0-b3b6-42f6-8ba4-aea436281a5d fwd="93.65.75.16" dyno=web.1 connect=0ms service=30ms status=200 bytes=1350
2017-02-13T18:10:02.096025+00:00 heroku[router]: at=info method=GET path="/chat/" host=gagliachat.herokuapp.com request_id=974bc
589-2fd7-4d12-af3f-c9c79b6a5d19 fwd="93.65.75.16" dyno=web.1 connect=3ms service=8ms status=304 bytes=237
2017-02-13T18:10:02.175145+00:00 heroku[router]: at=info method=GET path="/chat/index.js" host=gagliachat.herokuapp.com request_
id=8c2c4e30-6e25-4d73-b183-ae3e0a4eee33 fwd="93.65.75.16" dyno=web.1 connect=5ms service=6ms status=200 bytes=1350
2017-02-13T18:10:18.112287+00:00 heroku[router]: at=info method=GET path="/" host=gagliachat.herokuapp.com request_id=cb99f6b6-e
297-4147-b0c2-2aa5ef54b233 fwd="93.65.75.16" dyno=web.1 connect=1ms service=35ms status=302 bytes=246
2017-02-13T18:10:18.269114+00:00 heroku[router]: at=info method=GET path="/chat/index.js" host=gagliachat.herokuapp.com request_
id=6162d1c7-927f-4de5-b42a-80200b420ee7 fwd="93.65.75.16" dyno=web.1 connect=3ms service=6ms status=304 bytes=237
2017-02-13T18:10:18.176571+00:00 heroku[router]: at=info method=GET path="/chat/" host=gagliachat.herokuapp.com request_id=c6321
4a0-14a8-4c50-8a9a-b6963866c289 fwd="93.65.75.16" dyno=web.1 connect=3ms service=5ms status=304 bytes=237
2017-02-13T18:10:24.214602+00:00 heroku[router]: at=info method=GET path="/" host=gagliachat.herokuapp.com request_id=affe8338-1
3db-4842-b24f-d5e3b0f72b5d fwd="93.65.75.16" dyno=web.1 connect=0ms service=8ms status=302 bytes=246
2017-02-13T18:10:24.275116+00:00 heroku[router]: at=info method=GET path="/chat/" host=gagliachat.herokuapp.com request_id=b26ac
7b5-2fc3-4c50-80d8-3fde7afaa8fe fwd="93.65.75.16" dyno=web.1 connect=0ms service=2ms status=304 bytes=237
2017-02-13T18:10:24.342061+00:00 heroku[router]: at=info method=GET path="/chat/index.js" host=gagliachat.herokuapp.com request_
id=87535708-9e96-493e-968e-594b94e3fdf6 fwd="93.65.75.16" dyno=web.1 connect=0ms service=5ms status=304 bytes=237

This is my server-side Node.js code:

var express = require('express'),
  app = express(),
  port = process.env.PORT || 3000,
  path = require('path'),
  server = app.listen(port, function () {
    console.log('Server running on port ' + port)
  }),
  socket = require('socket.io'),
  io = socket.listen(server)

io.set('origins', '*:*')
io.set('match origin protocol', true)

app.use(express.static(path.join(__dirname, 'public')))

app.get('/', function (req, res) {
  res.redirect('/chat')
})

io.sockets.on('connection', function (socket) {
  console.log('New connection on: ' + socket.id)

  socket.on('msg', function (msg) {
    console.log(JSON.stringify(msg))
    socket.broadcast.emit('msg', msg)
  })

})

And this is my client-side code:

window.addEventListener('load', function () {
  var msgs = []
  var socket = io.connect('localhost:3000')
  socket.on('msg', function (msg) {
    msgs.push(document.getElementById('msgs').innerHTML += '<div><span style="color: red"> ' + msg.user + '</span>: ' + msg.msg + '</div>')
  })


  document.getElementById('send').addEventListener('click', function () {
    var userName = document.getElementById('yourId').value
    var msg = document.getElementById('message').value
    if (!userName || !msg) {
      alert('Please Insert a User name')
      return false
    } else {

      var msg = {
        user: userName,
        msg: msg
      }
      console.log('Sending msg: ' + JSON.stringify(msg))
      msgs.push('<div><span style="color: blue"> ' + msg.user + '</span>: ' + msg.msg + '</div>')
      updateMsgs(msgs)
      socket.emit('msg', msg)
    }
  })

  function updateMsgs(msgs) {
    document.getElementById('msgs').innerHTML = ''
    for (var i = 0; i < msgs.length; i++) {
      document.getElementById('msgs').innerHTML += msgs[i]
    }
  }
})

I hope you can help me. Thanks in advance!

This tutorial explains what you exactly need: https://devcenter.heroku.com/articles/node-websockets

The problem is that on client-side you are listening to the "localhost:3000", whereas you have to listen to server where you app is deployed.

Next code is common approach to connect to websocket:

var HOST = location.origin.replace(/^http/, 'ws')
var ws = new WebSocket(HOST);
var el = document.getElementById('server-time');
ws.onmessage = function (event) {
  el.innerHTML = 'Server time: ' + event.data;
};

If your website is hosted under address that is differ from your server side application (where websocket is created) you have to pass address of your server to WS constructor.

For example if your website available by address http://mywebsite.com whereas your websocket server available by address mywebsite.com:3000 you have to change string

var HOST = location.origin.replace(/^http/, 'ws');

to

var HOST = 'ws://mywebsite.com:3000';

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM