socket.io connections failing after integrating peer server in my code - javascript

hi as you know public server is down so i tried to host my on peer server
i already had a nodejs/express server up for chat ... so i tried to integrate peer server on my chat server
here is simplified version of my code
const env = require('dotenv').config({ path: '.env' })
const express = require('express');
const { ExpressPeerServer } = require('peer');
const fs = require('fs');
const app = express();
const https = require('https');
const http = require('http');
let server ;
if(env.parsed.PROTOCOL === 'https')
{
// server = create https server
}
else
{
server = http.createServer( app);
}
const { Server } = require("socket.io");
const io = new Server(server);
const peerServer = ExpressPeerServer(server, {
debug: true
});
app.use('/peerjs', peerServer);
io.sockets.on('connection', function(socket) {
console.log(`# connection | socket -> ${socket.id} |`);
});
var PORT = env.parsed.PORT || 8080
server.listen(PORT, () => {
console.log(`listining to port ${PORT} `);
});
the problem is after adding peer server to my code i cant establish any socket.io connection to the server ... i get no errors in the server i just get the client side error
WebSocket connection to 'ws://localhost:8080/socket.io/?EIO=4&transport=websocket' failed: Invalid frame header
server is up and working , if i type localhost:8080 in the browser i will get the response
if i remove peer server code it would work fine
i can move peer server to separate code and run on a different port but i prefer to keep it in this code
any idea why this happening ?

According to this issue, it's not possible to run socket.io and a PeerJS server on the same Express(/http(s) server) instance.
You should be able to start a separate PeerJS server from the same code file, as explained here:
const { PeerServer } = require('peer');
const peerServer = PeerServer({ port: 9000, path: '/myapp' });

Related

WebSocket - can't connect (Expected HTTP/)

I am using Node.JS and I am using http to use an express server which then my WebSocket is on, but when I try to connect to the socket it gives me an 'Expected HTTP/' error.
My code:
const express = require('express');
const app = express();
const server = require('http').createServer(app);
app.get('/', (req, res) => {
res.send("Hello World!");
});
const wss = new WebSocket.Server({ server });
// web socket stuff here
server.listen(port, () => {
console.log(`HTTP Server started on port ${port}`);
});
And then on another Node project, I have this to connect:
const WebSocket = require('ws');
const ws = new WebSocket.WebSocket('ws://localhost:3000/ws');
Any help?
//my memory in this question was that
const WebSocket = require('ws');
const socket = new WebSocket.Server({ port: 2424, host: "localhost"});
socket.on('connection', function(ws, wss) {
var domain = wss.headers.origin;
//etc...
But maybe you have a front for communicate if is not the good response ?

How to host an ExpressJS app with namecheap cPanel

I am trying to host my website, written with ExpressJS, using namecheap's cPanel, along with cloudflare, but can't seem to figure out how to deploy it. There isn't an option for a Node.js application so I resorted to using my cPanel's terminal to host it. Here's my basic ExpressJS code that I used for testing:
const express = require('express')
const https = require("https")
const fs = require("fs")
const app = express()
const cert = fs.readFileSync("./cert.crt")
const ca = fs.readFileSync("./ca.ca-bundle")
const key = fs.readFileSync("./private.key")
let options = {
cert: cert,
ca: ca,
key: key
}
let server = https.createServer(options, app)
app.get('/test', (req, res) => {
res.send('Hello World!')
})
server.listen(8080, 'shared ip', () => { console.log("Hosting!") });
Whenever I go to mydomain.com the index.html file gets served like normal, but when I go to mydomain.com/test I get a 404 not found. When looking at the GET request my site seems to be getting my server's IP with port 443 instead of 8080. Then when I go to mydomain.com:8080/test I get ERR_SSL_PROTOCOL_ERROR. I'm not totally sure how to fix this.
Port 443 is the standard TCP port that is used for website by default
try changing to server.listen(process.env.PORT || 80, () => { console.log("Hosting!") });
or server.listen(443, 'shared ip', () => { console.log("Hosting!") });

React/NodeJS won't speak via localhost in development

I'm working to setup a Node backend to feed data and communicate with ReactJS for my frontend. Ultimately I am developing new company software to replace our current Transportation System.
I utilize Amazon EC2 Ubuntu 16.04 - for my own reasons for my business - and I simply cannot get my ReactJS frontend with Socket.IO to communicate with my nodeJS backend with Socket.IO on http://localhost:4000/.
This is my App.js in my react frontend when it calls
import React, { Component } from 'react';
import logo from './logo.svg';
import ioClient from 'socket.io-client';
import './App.css';
var socket;
class App extends Component {
constructor() {
super();
this.state = {
endpoint: 'http://localhost:4000/'
};
socket = ioClient(this.state.endpoint);
}
This is my nodeJS index for the backend
const mysql = require('mysql');
const http = require('http');
const express = require('express');
const cors = require('cors');
const app = express();
const server = http.createServer(app);
const io = require('socket.io').listen(server);
app.use(cors());
app.get('/', (req, res) => {
res.send('Server running on port 4000')
});
const sqlCon = mysql.createConnection({
host: 'localhost',
user: 'admin-user',
password: 'admin-pass',
database: 'sample'
});
sqlCon.connect( (err) => {
if (err) throw err;
console.log('Connected!');
});
io.on('connection', (socket) => {
console.log('user connected');
});
server.listen(4000, "localhost", () => {
console.log('Node Server Running on 4000')
});
I can get it to communicate via my actual Public IP address, but not via localhost. I really don't want to expose my backend on my public IP address to communicate with it for all users. This has probably been asked before, but I honestly can't find a clear answer for it anywhere and I've been looking for 3 days now. Node has no problem executing, and like I said if I create the socket.io connection from the public IP, I can get it to communicate and as far as I can tell node has no problem running the rest of the script as it connects to mariaDB no problem.
This is the error I keep receiving in my Chrome console.
polling-xhr.js:271 GET http://localhost:4000/socket.io/?EIO=3&transport=polling&t=MvBS0bE net::ERR_CONNECTION_REFUSED
polling-xhr.js:271 GET http://localhost:4000/socket.io/?EIO=3&transport=polling&t=MvBS3H8 net::ERR_CONNECTION_REFUSED
I'm running React via npm start for the time being, so my localhost:3000 is being reverse proxied to nginx for my React frontend to be visible on my public EC2 IP via port 80.
Any help is appreciated!
It may be a cross origin request issue. Have you tried to enable CORS on your app. You can also use proxy in your react app package.json if you do not want to enable cors on your app.
In your react app package.json you can add
"proxy":"http://localhost:4000"
It's probably because the port you are using isn't available in the server-side when it's running.
Use the server-side port like this,
var port = process.env.PORT || 3000;
server.listen(port, "localhost", () => {
console.log('Node Server Running on 4000')
});
and on the client-side just connect to the app URL, like,
this.state = {
endpoint: '/'
};
socket = ioClient(this.state.endpoint);
Just clean up your server a bit. Take this guy run him from whatever terminal or ide you use to get your server going.
let startTime = Date.now();
const express = require('express');
const bodyParser = require('body-parser');
const compression = require('compression');
var cors = require('cors');
const app = express();
app.use(compression());
app.use(bodyParser.json({ limit: '32mb' }));
app.use(bodyParser.urlencoded({ limit: '32mb', extended: false }));
const http = require('http').Server(app);
const io = require('socket.io')(http);
app.use(cors({ origin: 'null' }));
const request = require('request');
const port = 4000;
let pm2InstanceNumber = parseInt(process.env.NODE_APP_INSTANCE) || 0;
http.listen(port + pm2InstanceNumber, err => {
if (err) {
console.error(err);
}
console.log('Listening http://localhost:%d in %s mode', port + pm2InstanceNumber);
console.log('Time to server start: ' + (Date.now() - startTime) / 1000.0 + ' seconds');
setTimeout(() => {
try {
process.send('ready');
} catch (e) {}
}, 2000);
app.get('/', (req, res) => {
res.send('Server running on port 4000')
});
});
or just run node filename.js to serve this guy up.

Adding socket.io to an existing Express project (with React on the front)

I have an existing project written in Express, where I've made a messaging system. Everything was working on POST/GET methods (to send and receive the messages).
I wanted to make them appear in real time, so I installed socket.io both on the client and server side. In my server.js I added these lines:
const http = require("http");
const io = require("socket.io");
const server = http.createServer();
const socket = io.listen(server);
and changed my app.listen(...) into server.listen(...).
Added also:
socket.on("connection", socket => {
console.log("New client connected");
socket.on('test', (test) => {
console.log('test-test')
});
socket.emit('hello', {hello:'hello!'});
socket.on("disconnect", () => console.log("Client disconnected"));
});
On the front part I put such code in the componentDidMount method:
const socket = socketIOClient();
socket.emit('test', {test:'test!'})
socket.on('hello', () => {
console.log('aaa')
})
Now I got 2 problems. Although the console.log() works correctly, I get an error on the React app:
WebSocket connection to 'ws://localhost:3000/sockjs-node/039/lmrt05dl/websocket' failed: WebSocket is closed before the connection is established.
Is that normal?
Also, when I change app.listen(...) into server.listen(...) in the server.js file, my routing stops working. All the POST and GET methods don't work, because the server is responding endlessly. Is that possible to use the socket.io just on a specific method in a specific routing file?
I keep my routes that way: app.use('/api/user', user); where user is a router file.
UPDATE:
full server.js require:
const express = require('express');
const mongoose = require('mongoose');
const dotenv = require('dotenv');
const bodyparser = require('body-parser');
const passport = require('passport');
const user = require('./routes/api/v1/User');
const company = require('./routes/api/v1/Company');
const http = require("http");
const io = require("socket.io");
const app = express();
dotenv.config();
app.use(passport.initialize());
require('./config/seed');
require('./config/passport')(passport);
const server = http.createServer();
const socket = io.listen(server);
You're not initializing server properly. Try making the following change
// const server = http.createServer();
const server = http.createServer(app);
and make sure you listen on server and not io
server.listen(PORT_GOES_HERE)
[UPDATE]
Working Example:
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(80);
// WARNING: app.listen(80) will NOT work here!
// DO STUFF WITH EXPRESS SERVER
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
For more details check this: https://socket.io/docs/

Socket.io setup causes hundreds of transport polling GET requests

I'm using express.js server-side and I followed the socket.io setup guide. Unfortunately the socket connection is never successful, and I receive an unruly amount of GET requests that look like this:
Here's my setup:
CLIENT - index.html
<script src="https://cdn.socket.io/socket.io-1.3.7.js"></script>
<script>
// var socket = io.connect('http://localhost');
var socket = io.connect('http://localhost:9000/');
socket.on('connected', function (serverData) {
console.log(serverData);
});
</script>
SERVER - /io/index.js
'use strict';
var socketio = require('socket.io');
var io = null;
module.exports = function(server) {
if (io) return io;
io = socketio(server);
io.on('connection', function(socket) {
console.log('Sockets connected!');
socket.emit('connected', 'Sockets connected!')
})
return io;
};
SERVER - app.js
'use strict';
// Set default node environment to development
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
var express = require('express');
var mongoose = require('mongoose');
var config = require('./config/environment');
// Connect to MongoDB
mongoose.connect(config.mongo.uri, config.mongo.options);
mongoose.connection.on('error', function(err) {
console.error('MongoDB connection error: ' + err);
process.exit(-1);
});
// Populate databases with sample data
if (config.seedDB) { require('./config/seed'); }
// Setup server
var app = express();
var server = require('http').createServer(app);
require('./config/express')(app);
require('./routes')(app);
// Setup sockets
require('./io')(server);
// Start server
function startServer() {
server.listen(config.port, config.ip, function() {
console.log('Express server listening on %d, in %s mode', config.port, app.get('env'));
});
}
setImmediate(startServer);
// Expose app
exports = module.exports = {
app: app,
server: server
}
This is tipically what happen, when client does not reach the server.
The client try again and again . . .
For that you have to check your config server-side, checking the port and the path is often the first things you should check.
In your case, maybe you should check this part :
//require('./io')(server); typo error ??
require('./io/index.js')(server);
More further you don't seem to give the good part :
( maybe depending on version you use)
// Setup server
var app = express();
var server = require('http').createServer(app);
require('./config/express')(app);
require('./routes')(app);
// Setup sockets
require('./io')(server);
I think it should be :
// Setup server
var app = express();
var server = require('http').createServer(app);
require('./config/express')(app);
require('./routes')(app);
// Setup sockets
//require('./io')(server); |O----------------------------------|
require('./io/index.js')(app);//<---we pass app as argument----|
I hope this will help you.

Categories

Resources