2

It deploys successfully and releases a successful build, but the socket.io module doesn't work for some reason. I've tried a variety of solutions that were posted on this forum but none seem to work for me. Oddly enough, it works fine on localhost but not on heroku, so I'm not sure what's up. Here's my code:

Server Side:

var express = require('express');
var socket = require('socket.io');

var app = express();
const PORT = process.env.PORT || 8080;


const server = app.listen(PORT, "0.0.0.0", function(){
    console.log('server is running on port: ' + PORT);
});

io = socket(server);

io.on('connection', (socket) => {
    console.log(socket.id);

    socket.on('SEND_MESSAGE', function(data){
        io.emit('RECEIVE_MESSAGE', data);
    })
});

Client Side:

import React from "react";
import io from "socket.io-client";

class Chat extends React.Component{
    constructor(props){
        super(props);

        this.state = {
            username: '',
            message: '',
            messages: []
        };


        this.socket = io.connect('localhost:8080');

        this.socket.on('RECEIVE_MESSAGE', function(data){
            addMessage(data);
        });

        const addMessage = data => {
            console.log(data);
            this.setState({messages: [...this.state.messages, data]});
            console.log(this.state.messages);
        };

        this.sendMessage = ev => {
            ev.preventDefault();
            this.socket.emit('SEND_MESSAGE', {
                author: this.state.username,
                message: this.state.message
            })
            this.setState({message: ''});

        }
    }
    render(){
        return (
            <div className="container" style={{width: '100%', height: '100%'}}>

                <div className="card" >
                    <div className="card-body">
                        <div className="card-title">Global Chat</div>
                        <hr/>
                        <div className="messages">
                            {this.state.messages.map(message => {
                                return (
                                    <div>{message.author}: {message.message}</div>
                                )
                            })}
                        </div>

                    </div>
                    <div className="card-footer">
                        <input type="text" placeholder="Username" value={this.state.username} onChange={ev => this.setState({username: ev.target.value})} className="form-control"/>
                        <br/>
                        <input type="text" placeholder="Message" className="form-control" value={this.state.message} onChange={ev => this.setState({message: ev.target.value})}/>
                        <br/>
                        <button onClick={this.sendMessage} className="btn btn-primary form-control">Send</button>
                    </div>
                </div>

            </div>
        );
    }
}

export default Chat;

I know the url isn't supposed to be 'localhost:8080' and I've tried other options like putting in the url as the heroku url such as 'my-app.herokuapp.com' but it always gives some error, which I'm not sure of and all the solutions I saw on this forum didn't work. Any help would be appreciated! Thanks in advance!

Khalil Hijazi
  • 411
  • 5
  • 15
  • did you add the port? `my-app.herokuapp.com:8080` – azium Apr 30 '18 at 02:48
  • Yes, it still doesn't work. When I do that, it doesn't give me an error in console, but socket.io still doesn't work for some reason. It's as if there's no communication between the server and the client. – Khalil Hijazi Apr 30 '18 at 03:46
  • Can you try this :const server = http.createServer(app).listen(config.port) ; also can you change var socket = require('socket.io') and io = socket(server); by just const io = require('socket.io')(server, { parameters you want }); as it is strange to have two times the declaration of socket for two different things – cagliostro Apr 30 '18 at 09:37
  • Still doesn't work. There aren't any errors in the console as well. – Khalil Hijazi Apr 30 '18 at 10:04
  • Possible duplicate of [How to connect socket.io with a Heroku-deployed React Native app?](https://stackoverflow.com/questions/50010719/how-to-connect-socket-io-with-a-heroku-deployed-react-native-app) – Milos Mosovsky Apr 30 '18 at 22:36

1 Answers1

0

Sorry for the comment above not really readable. Can you try this :

Server Side

    const http = require('http');
    const express = require('express');
    const io = require('socket.io');
    const app = express();
    const port = process.env.PORT || 8080; 
    const server = http.createServer(app).listen(port);
    io = require('socket.io')(server,{parameters});

Client Side :

 this.socket = io.connect(); //remove local host
cagliostro
  • 182
  • 1
  • 10
  • 1. you didn't require express in that and you put io before defining server but that's alright as I fixed those. So doing that, it didn't even work in localhost. I got two errors in the console: 1. Failed to load resource: http://localhost:3000/socket.io/?EIO=3&transport=polling&t=MCMquT- the server responded with a status of 404 (Not Found) 2. polling-xhr.js:263 POST http://localhost:3000/socket.io/?EIO=3&transport=polling&t=MCMqwwT 404 (Not Found) – Khalil Hijazi Apr 30 '18 at 13:53
  • oups sorry write in a rush will correct it, did you fix your issue ? – cagliostro Apr 30 '18 at 13:56
  • In fact you should have something like this at your client side below the other line this.socket = io(if(myenv === 'development') then 'localhost:8080' else '', {parameters}); – cagliostro Apr 30 '18 at 14:11
  • Okay, so I don't understand this whole thing with parameters. I didn't have any parameters for the server to begin with. But how would I do what you said? That is how would I do: this.socket = io(if(myenv === 'development') then 'localhost:8080' else '', {parameters}); – Khalil Hijazi Apr 30 '18 at 14:20
  • You need to tell socket from the client side where do you want it to connect basically. You were true on your first post it was good enough to connect on local host. if you want him to connect to heroku you need to do this.socket = io.connect(''); // Parameters are options you can give to socket you can see it later. – cagliostro Apr 30 '18 at 14:28
  • Could you give an example of how I would tell it to connect to localhost if it's in development mode and how I would tell it to connect to heroku otherwise? Let's say my url is at https://myapp.herokuapp.com Also, how come you put only one quotation mark in the io.connect() parameter? – Khalil Hijazi Apr 30 '18 at 14:59
  • Also, when I do io.connect(':8080'), that seems to work on localhost – Khalil Hijazi Apr 30 '18 at 15:18
  • That ^ doesn't work with heroku either. It doesn't give any console error output... – Khalil Hijazi Apr 30 '18 at 15:28
  • From the client you tell socket to connect to a special namespace. But it seems that you have an error more on your server side. Do you still have : app.listen(PORT, "0.0.0.0",... ? if so you should take a look on this question : https://stackoverflow.com/questions/18864677/what-is-process-env-port-in-node-js – cagliostro Apr 30 '18 at 15:34
  • Yeah, I'm not using that anymore. I'm literally using the code you provided me with lol – Khalil Hijazi Apr 30 '18 at 15:46
  • Ok i miss probably something will check later – cagliostro Apr 30 '18 at 15:51
  • Sure thing! I appreciate your help. Sorry for the trouble :( – Khalil Hijazi Apr 30 '18 at 17:17
  • Also, when you do come back, just wondering if this could be because I didn't put any script tags in index.html? – Khalil Hijazi Apr 30 '18 at 17:22
  • You don't need. Did you take a look at the heroku recommendation : https://devcenter.heroku.com/articles/node-websockets (option 2). After that I am clueless or will need a git repo to check but don't think i have the time for this. – cagliostro Apr 30 '18 at 19:00
  • suggest that you erase this question and make a new one with a better post and a git repo with just the necessary. I m sorry but don't have time right now to check your issue. – cagliostro May 01 '18 at 11:17
  • Yeah I did just that but nobody has answered it sadly. It's been more than 2 weeks and still no answer. – Khalil Hijazi May 17 '18 at 17:59