peerjs working on loaclhost but not on heroku? - express

I'm running my node server on 3000 port and peer server on port 3001.In this scenario its working properly.But when deployed over heroku i'm running my server at 3000 and peer server over 443. In this scenario peerjs not wroking. It might be port alloction issue i guess but i'm unable to find the issue.
peer.js
const myPeer = new Peer( {
secure:true,
host: 'my-app-name.herokuapp.com',
port: 443
})
server.js
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => console.log(`Server running on port ${PORT}`));
github link to project : link
New to Heroku. Any help will be appreciated!

Add this to your server file:
var ExpressPeerServer = require("peer").ExpressPeerServer;
var options = {
debug: true,
allow_discovery: true,
};
let peerServer = ExpressPeerServer(server, options);
app.use("/peerjs", peerServer);
And call on client side like this:
var peer = new Peer({
host: "yoursite.herokuapp.com",
port: "",
path: "/peerjs",
});

You Have to Host Two Apps on Heroku. First Your Main App and Second Your PeerJS Server. Because You Cannot Host your App On different Port (i.e. https://your-app-name.herokuapp.com:5000). And Then You can Connect Your Main App PeerJS Client With Your PeerJS Server by using this.
const myPeer = new Peer( {
secure:true,
host: 'my-peerjs-server-name.herokuapp.com',
port: 443
})
Happy Coding!

Just use this Heroku Element to deploy your own peer server with zero configuration. Connect to it from your client providing the host attribute as the url of your Heroku app without the https:// part and you may need to also set secure to true.
{
host: "you_app_name.herokuapp.com", // exclude protocol
secure: true
}

add this in server(index,app) file
const { ExpressPeerServer } = require("peer")
const peerServer = ExpressPeerServer(server, {
debug: true
})
app.use("/peerjs", peerServer);
and in client side add this
const myPeer = new Peer(undefined, {
path: "/peerjs",
host: "/",
port: "443",
})
port should same as your server.listen(port)
This will give invalid frame header for socket io but its fine

Related

API Call works for IPv4 Address (127.0.0.1) but get a "Error: connect ECONNREFUSED ::1:3001" when using localhost

So I have a very simple API call using fetch on my frontend to http://localhost:3001/test that gives me an error: Error: connect ECONNREFUSED ::1:3001
However, when I call that API directly (enter the api uri directly into my browser), it works just fine. Also when I change localhost to http://127.0.0.1:3001/test on my frontend fetch call, that works too.
This seems like it's gotta be a network error since ::1 and 127.0.0.1 resolve to the same address but one is IPv4 and the other is IPv6 right? Anyone have any thoughts on why this could be?
frontend fetch (BACKEND_URL = http://localhost:3001):
export async function getStaticProps() {
const res = await fetch(`${BACKEND_URL}/explore`, {
method: 'GET',
headers: {
"Content-Type": 'application/json',
Origin: BASE_URL,
},
});
...
}
Backend Server listening on port 3001 (PORT = 3001):
const PORT = process.env.PORT;
app.listen(PORT, '0.0.0.0', () => {
console.log(`Server is running on port ${PORT}`);
});
Stack: NextJS frontend, ExpressJS backend, MongoDB Atlas DB, NextAuth for auth
A couple of things can be the issue:
You need to enclose the IPv6 address between brackets, like http://[::1]:3001/test
The service is only listening on the IPv4 address and not on the IPv6 address. Depending on the server you may need to configure the listening address differently
Your post doesn’t contain enough information to go into more detail. Please edit your post to include the actual code, service and configuration so we can help you further.
When you use "localhost" in the backend URL, that is by default going to be resolved to the IPv6 address ::1. However, looking at the backend server code, that backend is listening on 0.0.0.0 which is IPv4.
You need to make that backend listen on IPv6:
const PORT = process.env.PORT;
app.listen(PORT, '::', () => {
console.log(`Server is running on port ${PORT}`);
});

Vue 2 devServer proxying does not work for websocket

I have simple web server in python running for example on 127.0.0.1:8080.
I can serve http-requests and web sockets.
This is example of server routes.
...
web.route('*', '/ws', ws_handler),
web.route('*', '/api/some_url', http_handler)
...
And I have frontend part of my application in Vue 2 JS.
I set up vue.config.js file for proxying dev server.
const host = "127.0.0.1"
const port = 8080
devServer: {
proxy: {
"/api": {
target:`http://${host}:${port}/`,
secure:false
},
"/ws": {
target:`ws://${host}:${port}/`,
ws:true,
secure:false,
changeOrigin:true
}
}
}
When I make http requests, for example
let res = await axios.get('/api/some_url');
everything works fine, but if I want to set up websocket connection
soc = new WebSocket('/ws');
I got error
Failed to construct 'WebSocket': The URL '/ws' is invalid.
For websockets my settings does not work.
Connection sets up and everything works fine if full address is provided.
soc = new WebSocket('ws://127.0.0.1:8080/ws');
I have read many articles and had no success for resolve my issue - how can I do proxying websocket connection for Vue JS dev server.
You should instantiate your WebSocket as ws = new WebSocket('ws://' + window.location.host + '/ws');

socketIO over SSL on Smartphone Browser

I have an Apache webserver with a valid SSL certificate. It runs my web application on it. Let's call it Server A.
Then I have a second server running a Node-Js server with a valid SSL certificate. There also socket.IO runs. And this one we call Server B.
A client requests the web application at server A and gets the desired page displayed. If the page is set up at the client, a connection to server B is established via websockets. If another client should change something on the page, it will be adapted for all currently connected clients.
Websockets work as desired. As long as the page is accessed via a computer browser.
If I now go to the website with my smartphone (Iphone 7) via Safari or Chrome (WLAN), no connection to the websocket server (Server B) is established.
Then I set up a small websocket example on http without encryption.
There the websockets work on the smartphone browser.
I hope I could describe my problem understandably. I am very grateful for hints, examples or similar.
// This script run on my Server
const fs = require('fs');
const server = require('https').createServer({
key: fs.readFileSync('myserver.key', 'utf8'),
cert: fs.readFileSync('myserver.cer', 'utf8'),
passphrase: ''
});
let io = require('socket.io')(server);
server.listen(3003);
io.on('connection', function (socket) {
console.log("User Connected connect " + socket.id);
socket.on('disconnect', function () {
console.log("User has close the browser " + socket.id);
});
socket.on('feedback', function (data) {
io.sockets.emit('feedback', data);
});
});
// On Clientsite
socket = io.connect('wss://adressOfServer:3003', {
// secure: true,
transports: ['websocket'],
upgrade: false,
rejectUnauthorized: false
//Here I have already tried many combinations
});
socket.on('connect_error', function (error) {
// alert(error);
});

How to use SSL correctly in Meteor?

I am using peerjs-server with self-signed certificates as follow (in the server):
var base = process.env.PWD;
var fs = Npm.require('fs');
var PeerServer = require('peer').PeerServer;
var server = PeerServer({
port: 9000,
path: '/',
ssl: {
key: fs.readFileSync(base + '/certificates/key.pem', 'utf8'),
cert: fs.readFileSync(base + '/certificates/cert.pem', 'utf8')
}
});
And connecting to it as follow (in the client):
window.peer = new Peer({
host: 'localhost',
port: 9000,
path: '/',
debug:3,
config: {'iceServers': [
{ url: 'stun:stun.l.google.com:19302' },
{ url: 'stun:stun1.l.google.com:19302' },
]}
});
The above code (client) works when I don't use self-signed certificates.
The problem I am facing now is, how to link those self-signed certificates in the client when connecting to the server?
Non of the examples I found like this one are using Meteor and I am struggling to achieve the same with meteor.
I am not familiar with PeerJS and it seems like its not working fully anyhow.
I would rather use Galaxy, or a self hosted linux server like AWS, DigitalOcean and run meteor build to create a regular node app.
If you then set the environmnent variable of the URL to "https://myapp.com", and also add the force-ssl package.
This will get your Meteor app to always use a secure connection.

Using https on heroku

I'm trying to get my app on heroku to be 'https everywhere'. So far the app is like this:
"use strict";
console.log('working');
//Initial setup
var path, https, privateKey, certificate, port, cdjshelp, util, cookies, oauth, twitter, crypto, _, options, express, auth, lodash, dust, dustjs,
dustjsHelpers, commonDustjsHelpers, app, db, fs, mongoose, mongooseTimes, Comment, Bird, Sighting, Site, User,
Backbone, io;
//node modules, express and dust declarations
path = require('path');
util = require('util');
fs = require('fs');
https = require('https');
privateKey = fs.readFileSync('./config/privatekey.pem').toString();
certificate = fs.readFileSync('./config/certificate.pem').toString();
crypto = require('crypto');
//APP Defn...
app = require('./config/appSetup')(dustjs);
//******** SERVER CONFIG **********//
var port = process.env['PORT'] = process.env.PORT || 4000; // Used by https on localhost
options = {
key: privateKey,
cert: certificate
}
https.createServer(options, app).listen(port, function() {
console.log("Express server listening with https on port %d in %s mode", this.address().port, app.settings.env);
});
I've used the openSSL CLI to generate a privatekey.pem and a certificate.pem and loaded them as options.
I know that heroku has a procedure if you're using DNS records to have the app serve to your own domain. I know that you have to go through the procedure listed here. I'm not remapping any urls or altering any records - my url is birdsapp.heroku.com.
Heroku uses piggyback SSL, so if you setup an http server your app will respond to https requests without any additional config. The problem there is that the http routes are still available, so I've stuck to setting an https server only - but it's timing out with nothing in the logs, so I think that there's a problem with the SSL setup.
Is the above setup correct? Is that the best way to do basic https server on heroku?
OK, it's actually much simpler than that...
You simply create an http server:
//******** SERVER CONFIG **********//
var port = process.env['PORT'] = process.env.PORT || 4000;
http.createServer(app).listen(port, function() {
console.log("Express server listening with http on port %d in %s mode", this.address().port, app.settings.env);
});
and add a route redirect:
app.all('*', function(req, res, next) {
if (req.headers['x-forwarded-proto'] != 'https')
res.redirect('https://' + req.headers.host + req.url)
else
next() /* Continue to other routes if we're not redirecting */
});
heroku takes care of the rest, setting up an http server which is a mirror of your http server and uses their certs, etc.