Socket.io works with localhost but not on Heroku server - node.js

I am currently trying to use socket.io and a node.js server to communicate with a Unity script. I have everything hooked up and working with localhost, but for some reason when I port it to my Heroku server it can't connect. I'm assuming it might have something to do with the URL's? I'm new to socket.io so any help would be appreciated.
My node.js server:
var express = require('express');
var app = express();
var expressWs = require('express-ws')(app);
var path = require('path');
var server = require('http').createServer(app);
var io = require('socket.io')(server);
io.on('connection', function(socket) {
socket.on('beep', function(){
socket.emit("speed", {data: 5});
console.log('beep recieved');
});
socket.on('change-speed', function(data) {
console.log('change speed recieved: ' + data);
socket.emit("speed", {newSpeed: data});
});
socket.on('ios-connection', function(data) {
console.log('ios connection with message: ' + data);
});
});
app.set('port', (process.env.PORT || 5000));
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
My connection URL:
ws://<heroku app name>.herokuapp.com:5000/socket.io/?EIO=4&transport=websocket

The problem is almost certainly an incorrect port number.
In your application, you are checking for process.env.PORT and if it is not set, you are defaulting to 5000.
In your ws URL however, you seem to be always expecting your application to be listening on port 5000.
You can check the config settings of your application by running the following command in the root of your project:
heroku run printenv
This will print a list of config vars, including the current set PORT value, eg:
PORT=9352
You should use this port when constructing your ws URLs, eg:
ws://your-app.herokuapp.com:9352/socket.io/?EIO=4&transport=websocket

I found the way!!.
In Unity
if you run server in the localhost. the url should have " : port"
example (port = 5000)
ws://127.0.0.1:5000/socket.io/?EIO=4&transport=websocket
but if you have deployed to **heroku
the url must delete " : port"
ws://<heroku app name>.herokuapp.com/socket.io/?EIO=4&transport=websocket
It's work for me!

I have deployed your code with minor changes and its working fine on heroku please take a look into it.
Server side app.js
var express = require('express');
var app = express();
app.set('port', (process.env.PORT || 5000));
var server = app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
var io = require('socket.io')(server);
app.use(express.static("./views"));
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
app.get('/', function (req, res) {
var path = __dirname + '/views/index.html';
console.log(path);
res.sendFile(path);
});
io.on('connection', function(socket) {
socket.on('beep', function(){
socket.emit("beep", {data: 5});
console.log('beep recieved');
});
socket.on('change-speed', function(data) {
console.log('change speed recieved: ' + data);
socket.emit("speed", {newSpeed: data});
});
socket.on('ios-connection', function(data) {
console.log('ios connection with message: ' + data);
});
});
package.json
{
"name": "socketio",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start" : "node app.js"
},
"author": "inampaki",
"license": "ISC",
"dependencies": {
"express": "^4.13.3",
"express-ws": "^0.2.6",
"socket.io": "^1.3.7"
}
}
index.html
<script src="/socket.io.js"></script>
<script>
var socket = io.connect('/');
socket.on('speed', function (data) {
console.log('speed Message Received!');
console.log(data);
});
socket.on('beep', function (data) {
console.log('beep Message Received!');
console.log(data);
});
socket.emit("beep", {beep : true});
socket.emit("change-speed", {"change-speed" : true});
socket.emit("ios-connection", {"ios-connection" : true});
</script>
note that save index.html and socket.io.js in views folder. URL on which I have deployed it is socketip

Ok, for some reason I tried everything on this question thread, and it worked. However not a single answer worked, but a combination of every one.
First, I removed the :PORT part in the URL, sort of like Chinnawat Sirima says. It is now...
ws://.herokuapp.com/socket.io/?EIO=4&transport=websocket
Then, for some reason initiating the server with this code from dangalg's answer/teyou's repo did work (I also noticed teyou's url doesn't have the port either).
var express = require('express');
var app = express();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
var PORT = process.env.PORT || 3000;
(more code here)
http.listen(PORT,function(){
console.log("Listening to port " + PORT);
});
Why do I say "for some reason"? Because I still don't know what I did lol. My guess is that I was setting the server in a way Heroku didn't like, but everyday localhost does. Because localhost doesn't care.
I'm just recompiling this because I've been in frustration with this problem for the last 8 hours, more or less. So I hope this helps someone else, to not lose valuable time and sleep.
(btw, I don't have a PORT variable in my Heroku, I have some other name, I guess that's another useless line but I'm not touching this anymore in case I break it again :D).

If you have deployed your application to Heroku, remove the port number from the URL of the server as given and it should work fine.
ws://<heroku app name>.herokuapp.com/socket.io/?EIO=4&transport=websocket When you test the app locally, you can access the socket via http://localhost:YOUR_PORT_NUMBER wheres, after deployment, you don't need to specify the port.

Had a bit of a nightmare with this. Ended up reading through the docs.
Server: https://www.npmjs.com/package/socket.io
Client: https://socket.io/docs/v4/client-initialization
It seems my structure was wrong see the docs.
In conjunction with Express
const app = require('express')();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
io.on('connection', () => { /* … */ });
server.listen(3000);
My full code.
const express = require('express')
const path = require('path');
const http = require('http')
const PORT = process.env.PORT || 5000
const app = express()
const server = http.createServer(app)
const cors = require("cors");
app.use(cors());
// Serve static files from the React app
app.use(express.static(path.join(__dirname, 'client/build')));
const io = require('socket.io')(server);
io.on("connection", (socket) => {
});
server.listen(PORT, () => console.log(`Server is running on port ${PORT}`));
And in my react code I am simply using.
const socket = io();
Hope this helps someone else

Related

Error occurred while trying to proxy request [...] from 192.168.0.4:3000 to http://192.168.0.4:5000 (ECONNRESET)

I'm working on my first project using react and node and have been stuck on this problem for a while. I keep getting this error when trying to connect to my site using the ip address, but if I just do localhost:3000 it works perfectly. I want to be able to connect via the IP address so I can test it across devices. Here is the full error:
[HPM] Error occurred while trying to proxy request /socket.io/?EIO=3&transport=polling&t=N4EqtUl&sid=kz_I098ZM2h1Z6WZAAAI from 192.168.0.4:3000 to http://192.168.0.4:5000 (ECONNRESET) (https://nodejs.org/api/errors.html#errors_common_system_errors)
I checkout out this post and implemented setupProxy.js like the second answer suggested, but it still isn't working.
Here is my node server (index.js):
const express = require('express');
const app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
const path = require('path')
const port = process.env.PORT || 5000;
app.use(express.static(path.join(__dirname, 'client/build')));
io.on('connection', function(socket) {
console.log('a user connected');
});
// Anything that doesn't match the above, send back index.html
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname + '/client/build/index.html'))
})
http.listen(port || 5000, function () {
console.log('listening on', port);
});

Express launching Angular application

I have an express server setup online which loads multiple ports and those ports are setup on subdomains for example. port 9000 loads the main domain.com port 8000 loads the main application at "app.domain.com" port 1000 loads "signup.domain.com" and the build version of the app is on port 8500 "build.domain.com".
The application is an Angular application however when I go to load the Angular app it loads on port 4200 or it says 8500 is in use. So currently I am loading that in express like so:
// Build Application - In Development
var appbuild = express();
appbuild.get('/', function (req, res){
res.sendFile('/app/build/myapp/src/index.html', { root: '.' })
});
var port = 8500;
appbuild.listen(port);
console.log('Build App Listening on port', port);
So my question is in Express how can I instead of writing sendfile command make it launch the angular app in that location on port 8500 so my subdomain names will work. The reason I'm asking this is because right now all it does is load the index file but angular or the app isn't running so i just see source code that says app-root and a blank white page.
Thank you in advance.
Robert
--- Update. I've decided to post the entire Express file. My issue is trying to load a angular app on port 8500 from the subfolder upon booting of express. Here is the full server.js code:
// server.js
const express = require('express'),
path = require('path'),
bodyParser = require('body-parser'),
cors = require('cors'),
mongoose = require('mongoose'),
config = require('../config/DB');
mongoose.Promise = global.Promise;
mongoose.connect(config.DB).then(
() => {console.log('Database is connected') },
err => { console.log('Can not connect to the database'+ err)}
);
// Main Website
var web = express();
web.get('/', function (req, res){
res.sendFile('/web/index.html', { root: '.' })
});
var port = 9000;
web.listen(port);
console.log('Web Listening on port', port);
// Main Application
var app = express();
app.get('/', function (req, res){
res.sendFile('/app/index.html', { root: '.' })
});
var port = 8000;
app.listen(port);
console.log('Main App Listening on port', port);
// Build Application - In Development
var appbuild = express();
appbuild.get('/', function (req, res){
res.sendFile('/app/build/myapp/src/index.html', { root: '.' })
});
var port = 8500;
appbuild.listen(port);
console.log('Build App Listening on port', port);
// Sign up Portal
var sign = express();
sign.get('/', function (req, res){
res.sendFile('/signup/index.html', { root: '.' })
});
var port = 10000;
sign.listen(port);
console.log('Sign Up Portal Listening on port', port);
Refer to this link https://malcoded.com/posts/angular-backend-express
Update your code to the following:
const express = require('express');
const app = express();
app.listen(8500, () => {
console.log('Server started!');
});
You need to build the angular app if your angular version not 1.x
ng build
Also, I think this question is similar to your question:
Not able to view Angular app via express/heroku?

Socket.io not working on node server

I'm running a server and all it needs to do is connect to a 3rd party public socket.io stream. I have it working in my react app but can't get it to work on my server. I'm using node and express.When I run I get no errors. Here is my code
var express = require("express");
var app = express();
var port = 3000;
var io = require('socket.io-client/dist/socket.io');
var socket = io.connect('http://socket.coincap.io', {transports: ['websocket']});
socket.on('trades', function(tradeMsg) {
console.log("worked");
});
app.listen(port, () => {
console.log("Server listening on port " + port);
});
Just checked my code, I do something like the following which is a bit different than your code. Don't know if it's your solution but maybe that could helps you.
In a separate socket-io.js
module.exports = function (app, server) {
var socketIO = require('socket.io').listen(server, {'transports': ['websocket']});
global.socketIO = socketIO;
socketIO.set('origins', '*:*');
socketIO.sockets.on('trades', function (tradeMsg) {
console.log("worked");
});
};
Then in my www after var server = http.createServer(app); I've got:
require('socket-io')(app, server);
You can try installing socket.io-client using npm.
npm install socket.io-client --save
And try running the following code. It should work fine.
var express = require("express");
var app = express();
var port = 3000;
var socket = require('socket.io-client')('http://socket.coincap.io');
socket.on('trades', function(tradeMsg) {
console.log("worked");
});
app.listen(port, () => {
console.log("Server listening on port " + port);
});

socket.io not working node.js

I am not able to run socket.io code in node.js, console.log() is also not displaying when running the code. Below is the code.
app.js
var express = require('express');
var http = require('http');
var app = express();
app.set('port', process.env.PORT || 3000);
app.post('/testStream',test.testStream);
var server = http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
module.exports.appServer = server;
and I have created a test.js file where I am accessing this exported variable appServer.
var server = require('../app.js');
exports.testStream = function(req,res){
var io = require('socket.io').listen(server.appServer);
io.on('connection',function(socket){
console.log("in socket");
fs.readFile('E:/temp/testimg.png',function(err,buf){
socket.emit('image',{image: true,buffer: buf});
console.log("test image");
});
})
}
when the code runs it stucks and not showing the console.logs(). What I am doing wrong over here. Any help is very much appreciated.
I would suggest following the code structure as suggested in socket.io docs.
Also, you should not be calling io.listen or io.on('connection') inside your testStream express middleware. These are things you should only be doing once, and ideally they should happen during startup, inside app.js and not in reaction to a POST request. In fact, I'm not sure what the purpose of your testStream middleware is, its not even returning any response (eg res.end())
If you want to handle socket connections in a separate module you can, but instead of exporting your app's server the way you are, try passing the io instance as variable to your submodule. In short, try this:
app.js
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var test = require('./test')(io);
app.set('port', process.env.PORT || 3000);
server.listen(app.get('port'), function() {
console.log('Express server listening on port ' + app.get('port'));
});
test.js
module.exports = function(io) {
io.on('connection', function(socket) {
console.log("in socket");
fs.readFile('E:/temp/testimg.png', function(err, buf) {
socket.emit('image', {
image: true,
buffer: buf
});
console.log("test image");
});
});
};

Socket.io.js returns 404 on OpenShift

I'm new to node.js and I'm trying to create a chat app following the tutorial on socket.io's website. I've got it working on my local machine, but now I'm trying to upload it to an OpenShift Server.
In my app, I have the line:
<script src="/socket.io/socket.io.js"></script>
On my local machine, it loads fine, but on my server, it returns a 404 error. I thought that my node_modules might not be loading at first, but after shh-ing into the server and checking, I see they are present.
My dependencies in my package.json are as follows:
"dependencies": {
"express": "^3.4.8",
"socket.io": "^1.1.0"
}
There are many different questions on here about getting a 404 error from socket.io and I've gone threw many of them them attempting to solve this issue, with no progress. Including changing the script src to:
http://app-domain.rhccloud.com
http://app-domain.rhccloud.com:8000
http://app-domain.rhccloud.com:8080
ws://app-domain.rhchloud.com:
Most of the suggestions aren't specific to an OpenShift server so I figured I'd ask specifically about it.
If needed, here's my server.js:
#!/bin/env node
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
var port = process.env.OPENSHIFT_NODEJS_PORT || 8080;
var ip = process.env.OPENSHIFT_NODEJS_IP || "127.0.0.1";
app.get('/', function(req, res){
res.sendfile('index.html');
});
app.listen(port,ip,function() {
console.log('listening');
});
io.on('connection',function(socket) {
console.log('a user connected');
socket.on('disconnect',function() {
console.log('user disconnected');
});
socket.on('chat message',function(msg) {
io.emit('chat message',msg);
});
});
Thanks for any assistance.
Should be:
server.listen(port,ip,function() {
console.log('listening');
});
not app.listen.

Resources