Heroku app w/ socket.io refuses connection or sends 404 - reactjs

After days of trying to figure out what's wrong, I came here to seek help.
My Heroku app is using React as frontend and Socket.io as backend. Here's the drill:
Heroku runs dyno with command "npm run start", which is set to concurrently 'npm run react' 'npm run server' to run both front and back ends.
But even if I make it work (can't really even explain how), it only works on my computer. If I try going to the same page on my phone, no requests are made and I can't even tell why, since there is no debug log.
Here is my /src/server/index.js file:
const express = require("express");
const app = express();
const server = require("http").Server(app);
const io = module.exports.io = require('socket.io')(server)
const port = process.env.PORT || 80
const socketManager = require('./SocketManager') // All functions there
io.on('connection', socketManager);
// app.use(express.static(__dirname + '/../../build'))
server.listen(port,() => {
console.log("Listening on port", port)
})
I use config file to dynamically change for the server url.
let server = 'https://hidden-waters-73936.herokuapp.com/socket.io/?EIO=4&transport=websocket'; // 404
// let server = window.location.hostname; // 404, same as above
// let server = 'http://localhost:4001'; // works locally on heroku
// let server = '/'; // 404, not found, AND CONNECTION_REFUSED
// let server = 'https://127.0.0.1:4001'; // CONNECTUIN_REFUSED
// let server = 'http://0.0.0.0:4001'; // Doesn't work at all
module.exports = server;
Commented out lines are those that I tried. Last try was changing https to ws, as someone recommended earlier, then I tried adding .com:80/socket.io..., but still no luck. Every time it's a different Error
Here's what the errors are like with uncommented server variable:
https://imgur.com/Lf0BxV3
I expect it to make successful requests both on my computer and phone. I'll try my laptop to see the logs and check back if I find anything useful.
**UPDATE for #Ashish
React component
import server from '../../config/serverConfig'
const socket = socketIOClient(server);
componentDidMount() {
socket.emit("test", {});
}
** EDIT:
My Heroku logs seem to tell me something else is going on:
2019-05-13T16:59:55.472135+00:00 app[web.1]: [1] [33m[nodemon] 1.19.0[39m
2019-05-13T16:59:55.474073+00:00 app[web.1]: [1] [33m[nodemon] to restart at any time, enter `rs`[39m
2019-05-13T16:59:55.475362+00:00 app[web.1]: [1] [33m[nodemon] watching: *.*[39m
2019-05-13T16:59:55.477060+00:00 app[web.1]: [1] [32m[nodemon] starting `node src/server/index.js`[39m
2019-05-13T16:59:56.164302+00:00 app[web.1]: [1] Listening on port 40497
2019-05-13T16:59:56.573081+00:00 heroku[web.1]: State changed from starting to up
2019-05-13T16:59:57.538639+00:00 app[web.1]: [0] Something is already running on port 40497.
2019-05-13T16:59:57.585807+00:00 app[web.1]: [0] npm run react exited with code 0
2019-05-13T17:01:19.780332+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=GET path="/" host=hidden-waters-73936.herokuapp.com request_id=42a6c345-94b7-441a-afde-82c1e9c52e97 fwd="90.191.14.93" dyno=web.1 connect=1ms service=30004ms status=503 bytes=0 protocol=https

Solution:
At least for me it works for now. Here's what I changed:
server config file (AKA what client is listening for)
let server = window.location.hostname;
const env = process.env.NODE_ENV;
if (env === 'development') {
server = 'http://localhost:4001';
console.log("Using dev port")
}
module.exports = server;
package.json
"scripts": {
"client-install": "npm install",
"start": "node src/server/index.js",
"server": "nodemon src/server/index.js",
"client": "npm start",
"build": "react-scripts build",
"react": "react-scripts start",
"dev": "concurrently \"npm run server\" \"npm run client\"",
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install && npm run build"
Heroku procfile:
web: npm start
HOWEVER.
I use React Router to navigate through different pages. As soon as a page is refreshed on heroku, it returns "Not found". I suppose it is looking for a .html file with the path name, but I need it to rewrite to index.html like Firebase does.
I tried using create-react-app-buildpack, with the nginx thing and it seems to crash my server with
Failed to load resource: the server responded with a status of 405 (Not Allowed)
and then changes listening point (I suppose)
polling-xhr.js:269 POST https://XXXXXXXXXX.herokuapp.com/socket.io/?EIO=3&transport=polling&t=MgpToRX 405 (Not Allowed)
Is there a way to determine why the problem is occuring? Heroku logs dont seem to tell anything useful.

Related

how to configure ecosystem.config.js file for next.js on apache

am trying to deploy nextjs app on apache using pm2.
I have installed latest versions of node, pm2. and apache is configured as reverse proxy.
but when am trying to start daemon process, it is not doing it. I cloned a project from github and ran 'npm run build, which created .next file and in that file, I created ecosystem.config.js file for pm2, it looks like this :
module.exports = {
apps : [{
name: "nextjs-app",
script: "npm",
args: "run build",
env: {
NODE_ENV: "production"
}
}]
};
but when I ran pm2 start npm -- start , terminal is giving me respone like this:
pm2 start npm -- start
[PM2] Spawning PM2 daemon with pm2_home=/home/georgianar/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Starting /usr/local/bin/npm in fork_mode (1 instance)
[PM2] Done.
but when I try to see list of process, there is none, and when user tries to enter the website, site log shows that there is no service on port 3000
(111)Connection refused: AH00957: http: attempt to connect to 127.0.0.1:3000 (localhost:3000) failed
and
AH01114: HTTP: failed to make connection to backend: localhost
I dont know why, any idea why it is doing so?

CodePipeline + Beanstalk Connection Refused React + Express Apps

I'll lay this out below in detail:
Goal
A React front-end game that uses socket.io to transfer game state data between players on the Express server.
Setup
After finding that it would be impossible/a real work-around to have both React/Express on an Amplify instance, I decided to move to CodePipeline + CodeDeploy to Beanstalk.
I have the Source coming from GitHub, a CodeBuild step, and then CodeDeploy. The CodeBuild should basically just compile based on my buildspec.yml below:
version: 0.2
frontend:
phases:
preBuild:
commands:
- npm ci
build:
commands:
- npm run build
artifacts:
baseDirectory: build
files:
- '**/*'
cache:
paths:
Although this is calling npm run build, which I'm not sure A) The CodeBuild/CodeDeploy will try to do with node start or B) If this will kick off my react-scripts build in package.json:
"scripts": {
"webpack": "webpack --production",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
I'm assuming I want it to build the webpack bundle in CodeBuild, then CodeDeploy will call the proper run command, but it seems black boxed? Is there another config file?
Runtime Errors
I get Connection Refused, although my server.js file defaults to localhost and 8080:
var hostname = process.env.IP || 'localhost';
var port = process.env.PORT || 8080;
Web.std.out.log:
Sep 20 18:10:10 ip-172-31-41-5 web: > MyApp#0.1.0 start /var/app/current
Sep 20 18:10:10 ip-172-31-41-5 web: > react-scripts start
Sep 20 18:10:12 ip-172-31-41-5 web: #033[34mℹ#033[39m #033[90m「wds」#033[39m: Project is running at http://172.31.41.5/
Sep 20 18:10:12 ip-172-31-41-5 web: #033[34mℹ#033[39m #033[90m「wds」#033[39m: webpack output is served from
Sep 20 18:10:12 ip-172-31-41-5 web: #033[34mℹ#033[39m #033[90m「wds」#033[39m: Content not from webpack is served from /var/app/current/public
Sep 20 18:10:12 ip-172-31-41-5 web: #033[34mℹ#033[39m #033[90m「wds」#033[39m: 404s will fallback to /
Sep 20 18:10:12 ip-172-31-41-5 web: Starting the development server...
Ngnix error.log: 2020/09/18 03:07:30 [error] 4436#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.31.40.133, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "172.31.41.5"
Lot of moving parts so I'm sure there are several missteps here, not sure which is which.
Based on the comments.
By default EB will look for package.json to run your application. If it is missing, and will use use script option in your package.json to start your application. For example, if you start sample node.js application that EB provides, the file is:
package.json
{
"name": "Elastic-Beanstalk-Sample-App",
"version": "0.0.1",
"private": true,
"dependencies": {},
"scripts": {
"start": "node app.js"
}
}
If you don't provide package.json nor Procfile (other option, see below) EB will expect app.js or server.js to be present to start your application.
If you don't want to use package.json, you can also use Procfile to tell EB how to start your application.
When you don't provide a Procfile, Elastic Beanstalk runs npm start if you provide a package.json file. If you don't provide that either, Elastic Beanstalk looks for the file app.js or server.js, in this order, and runs it.
Example in your case could be
web: serve -s build

HTTPS in development environment

I use letsencrypt certificate on my server. When running my app with HTTPS=true npm start command, I have an error when browsing my app.
SecurityError: Failed to construct 'WebSocket': An insecure WebSocket
connection may not be initiated from a page loaded over HTTPS.
Here is my config:
in package.json
"start": "react-scripts start",
"prestart": "(cat /etc/letsencrypt/live/domainxxx/cert.pem /etc/letsencrypt/live/domainxxx/privkey.pem > ./node_modules/webpack-dev-server/ssl/server.pem) || :",
(running on debian 9 server)

webpack-dev-server open and host opens wrong URL

Per the docs here and here, I have the following in my package.json
"scripts": {
"start": "webpack-dev-server --host 0.0.0.0 --open",
...
With just --open it opens localhost:8080 when I run npm start. When I add in --host 0.0.0.0 it still opens, but opens 0.0.0.0:8080 and gives me ERR_EMPTY_RESPONSE in the browser. I can manually change it to localhost:8080 and it loads the page just fine.
I tried --host 0.0.0.0 --open --open-page localhost:8080 and it dutifully opens http://0.0.0.0:8080/localhost:8080 for me in the browser.
Has anyone gotten these two options to play nicely together?
Below works fine for me
webpack-dev-server -p --public 127.0.0.1:9000 --host 0.0.0.0 --port 9000
--host is the listening interface. --public is for what would be opened in the browser. And --open-page is for appending the page url after the main domain

Could not proxy request /pusher/auth from localhost:3000 to http://localhost:5000 (ECONNREFUSED)

I am trying to create a chat app using reactJS and pusher, i am getting this error-
Could not proxy request /pusher/auth from localhost:3000 to
http://localhost:5000 (ECONNREFUSED)
in package.json file i have set proxy as-
"proxy": "http://localhost:5000"
and my localhost is defined as 127.0.0.1 in /etc/hosts file.
I have also checked for the port availability using netstat, but these all seems to be correct. Can anybody help?
I had a same problem in my React App and I fixed it by just adding "/" after the port number in package.json file (so now it's: "proxy": "http://localhost:5000/")
I faced a similar issue but in Mac machine. I changed localhost to 127.0.0.1 and that worked for me.
For windows:
"proxy": {
"/auth/google": {
"target": "localhost:5000"
}
}
For Mac:
"proxy": {
"/auth/google": {
"target": "http://127.0.0.1:5000"
}
}
In your server package.json add --ignore client to your "start" or "server" scripts. So it would look like this:
"scripts": {
"start": "node index.js",
"server": "nodemon index.js --ignore client"
}
In server directory
npm install --save http-proxy-middleware
then create a file with this name : setupProxy.js
in src directory of client react folder
then add the following
const proxy = require("http-proxy-middleware");
module.exports = function(app) {
app.use(proxy("/api/**", { // https://github.com/chimurai/http-proxy-middleware
target: "http://localhost:5000",
secure: false
}));
};
In proxy configuration make sure you are matching any path
with double ** not only *
Note: you are not going to require this proxy anywhere else
just like that
Note: remove any other proxy settings in package.json
For more check this reference
I think You have not start your Back end server. Try start both Back end and Front end server concurrently. Just simply run npm start in both back end and front end.
In your node module include
{
...
"proxy": "http://127.0.0.1:5000"
}
Where the ... simply means you should append the proxy ip to it.
Also, if you are using axios, doing axios.post('api/users') works and not axios.post('/api/users')
For those who are using Docker, if your docker-compose.yml looks like:
services:
app:
...
depends_on:
- api
ports:
- 3000:xxxx
...
api:
...
ports:
- 5000:xxxx
...
Then we should set the proxy URL to
"proxy": "http://host.docker.internal:5000"
In package.json file just add "/" after the port number and it should work fine.
"proxy": "http://localhost:5000/"
I have similar issue.
The problem was that server was listening on ipv6 ::1 address
and the proxy was connecting to ipv4 127.0.0.1
I changed both addresses from localhost to 127.0.0.1
Use
"proxy":"http://localhost:PORT_NUMBER/"
in package.json
and in axios backend call route like
use axios.get("api/user/getinfo") instead of axios.get("/api/user/getinfo");
None of these answers were helping me despite everyone's effort. Finally, thankfully, I found this github discussion where someone said use node server.js to start the server. This WORKED. Before I was using nodemon server.js and npm start. I've no idea why those commands weren't able to connect to my proxy at http://127.0.0.1:5000 but node server.js could.
Cheers
I think Server not working properly, you should run client and server concurrently for that add following procedures in package.json file
1) Install concurrently
npm install concurrently --save
2) configure client and server
"server": "nodemon server.js",
"client": "npm start --prefix client"
3) configure concurrently
"dev": "concurrently "npm run server" "npm run client""
if you are not using concurrently at your server side then simply run each front-end and back-end separately such that server side should run first and client side last.
Changing localhost to [::1] solved my problem.
Taken from here https://forum.vuejs.org/t/proxy-error-with-vue-config-js-and-axios/110632/4?u=mahmoodvcs
This has something to do with default settings of create-react-app.
I found a solution from Github Issue. Read the response by danielmahon on 15 Mar 2018
"proxy": {
"/api": {
"target": "https://localhost:5002",
"secure": false
}
},
If you can't connect to localhost on port 5000 via telnet (you can download and use PuttY if you don't have telnet installed), then that means that server isn't running.
If you're using a Windows machine, go to your package.json for the server that is running on port 5000 and change this line:
"start": "./node_modules/.bin/concurrently \"./node_modules/.bin/nodemon\" \"npm run client\"",
To this:
"start": "./node_modules/.bin/concurrently \"npm run server\" \"npm run client\"",
Watch your build messages and you should see something similar to the following:
[0] 🌎 ==> API Server now listening on PORT 5000!
[1] Starting the development server...
[1]
[1] Compiled successfully!
[1]
[1] You can now view chat app in the browser.
[1]
[1] Local: http://localhost:3000/
[1] On Your Network: http://192.168.1.118:3000/
[1]
[1] Note that the development build is not optimized.
[1] To create a production build, use yarn build.
My issue was trying to run my react project with docker containers open.
Change the ports or shut down the containers.
In my case the problem was that I have been accessing the PORT by the wrong name, i had it PORT instead of SERVER_PORT which was my correct environment variable name. So this problem means that there is a something wrong in your code, in my case the port on which the server should be running was undefined.
Proxy error: Could not proxy request /signup from localhost:3000 to http://localhost:8282/. See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNREFUSED).
I got the same issue and I just solved it by only restart both of the server, you need to run both of the server running.
Thanks me ltr:)
If you are using axios, then follow this.
Using proxy might not work sometimes. There is a standard way to solve this issue.
For that we need to configure our axios before sending requests. axios has a method to set the baseURL create() Create a new file http.js in your src folder.
import axios from 'axios'
const http = axios.create({
baseURL: "http://localhost:5000"
headers: {
Accept: "application/json",
"Content-Type": "application/json"
}
})
export default http
Now insted of using using axios for sending request, use this
import axios from "../../http";
happy coding!
In my case, I changed port number from 5000 to 7000, while reactjs was still fetching on localhost 5000, after I changed everything worked perfect
ReactJs FETCH HOOK:
const { data, loading, error } = useFetch(
"http://localhost:7000/api/hotels/countByCity?cities=Arusha,Dodoma,Mwanza,Dar-es-salaam"
);
NodeJS server port:
const PORT = process.env.PORT || 7000;
I recently got this error when waiting for a response from my rest API function which does not return any.
so you either need to change the API implementation and send something back to the client or just don't wait for a response if you are not returning any.

Resources