Websocket server on subdomain only - javascript

I'm trying to have a websocket server on a subdomain so the client would point to something like 'ws://ws.mydomain.com'.
I'm using the subdomain module to handle normal get requests to subdomains but not sure how to consolidate the two. Any ideas on how I can approach this?
The WebSocketServer can take a server object, but can't figure it out.
var WebSocketServer = require('ws').Server
var express = require('express');
var subdomain = require('subdomain');
var app = express();
var wss = new WebSocketServer({port: 8081, server: http.Server});
app.use(subdomain({ base: 'mydomain.com', removeWWW: true}));
wss.on('connection', function(ws){
console.log('a connection!');
});
app.get('/subdomain/unrelatedsub', function(req, res){
res.send("hello unrelated subdomain page");
});
app.listen(80);
Link to WS documentation

From the web socket protocol:
The WebSocket Protocol attempts to address the goals of existing
bidirectional HTTP technologies in the context of the existing HTTP
infrastructure; as such, it is designed to work over HTTP ports 80
and 443 as well as to support HTTP proxies and intermediaries, even
if this implies some complexity specific to the current
environment.
Express 3 exposes the app as a request handler, you must instantiate a http.Server first which you can pass the express app into, and then you setup your sockets, as the ws:// protocal can share the HTTP port you listen on, just as wss:// would share the HTTPS port.
Try something closer to this, I will test when get a chance if you haven't responded:
var WebSocketServer = require('ws').Server
var express = require('express');
var http = require('http')
var app = express();
app.use(subdomain({ base: 'mydomain.com', removeWWW: true}));
var server = http.createServer(app);
server.listen(8080);
var wss = new WebSocketServer({server: server});
wss.on('connection', function(ws){
console.log('a connection!');
});
app.get('/subdomain/unrelatedsub', function(req, res){
res.send("hello unrelated subdomain page");
});

Related

What do I replace "http://localhost:3000" with when using a server and not local machine?

I've been doing a lot of online courses with node and express. I want to get sockets.io to work but I can't even establish a connection at the moment. I am using a cPanel virtual private server and running code in the server terminal and then trying to use a website hosted on the server to access the .js file running on the server.
I've tried all sorts of different things but I'm reducing it to its most basic level to try get a connection. All the videos I've seen are running on a local machine and using the command prompt on a local machine to run the .js file and the browser to access http://localhost:3000.
The .js file I'm running on my cPanel server looks like this;
var express = require('express');
var app = express();
app.get('/', function(req,res){
res.send('Hello world 2');
})
app.listen(3000);
So how do I then access that via the browser? I have tried http://mywebsite.com:3000 and http://11.22.33.444:3000 if 11.22.33.444 is the server ip, but the browser just times out and there is no output in the server console.
ultimately I need to run a socket.io command that looks like this;
var socket = io.connect('http://localhost:3000');
and in all the tutorials I've seen they use this localhost:3000 but no one explains how to access this if its on an actual server so I'm pretty lost.
There are other examples like;
...
const http = require('http').createServer();
...
http.listen(3000 => () => {
console.log('listening on port 3000');
});
That's just a snippet of the code but I'm wondering how I then access that 3000 port from the browser without http://localhost:3000
IF you read the docs you will see that there is a guide how to connect it with express: https://socket.io/docs/
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(3000);
// WARNING: app.listen(3000) will NOT work here!
app.get('/', function (req, res) {
res.status(200).json({ message: "Connected" });
});
io.on('connection', function (socket) {
console.log("somebody connected");
});
Think I just solved it. I tried a different port and it worked :/
No need to specify any address in io.connect()
const app = express();
const http = require('http').Server(app);
const io = require('socket.io')(http);
http.listen(process.env.PORT || 3000, function() {
});
<script src="/socket.io/socket.io.js"></script>
var socket = io.connect();

Problem with socket when using it in express

I have a problem with the socket in my program. export the "io" connection and although I can broadcast from any part of the normal program (just by referring to "io"), I cannot use "socket" and broadcast with it unless it is within the same connection of "io." I would like to know how to use socket from any other part of the program, with functions such as "socket.emit ()" or "socket.broadcast.emit" etc. Or how to call this one.
This is my index.js:
const express = require('express');
const restApi = express();
const cors = require('cors');
const server = require('http').createServer(restApi);
const rutas = require('./src/routes/Routes.js');
const io = require('./src/socket/SocketManager.js');
io.attach(server);
restApi.use(express.json());
restApi.use(express.static('public'));
restApi.use(cors());
restApi.options('*', cors());
server.listen(4040, () => console.log('Listening server in port 4040'));
restApi.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
restApi.use('/api',rutas);
my managersocket.js:
const io = require('socket.io')();
io.on('connection', function (socket) {
console.log('NUEVA CONEXION: ',socket.id);
socket.emit('recoger',socket.id);
});
module.exports = io;
This is where I would like to use the socket or at least call the function.
and User.js:
var io = require('../../socket/SocketManager');
var RouterUser = function(){
this.practicafuncion = function (req,res){
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
console.log('probando entrar por rest y que salga un mensaje por socket');
res.send({
status:'Aprobado',
msj:'Enviado por rest'
});
//this works correctly. io.sockets.emit('mensaje','**MENSAJESERVIDORPORSOCKET**');
//This is not the problem when using "socket". socket.broadcast.emit('mensaje','**MENSAJESERVIDORPORSOCKET**');
};
}
module.exports = function(){
var instancia = new RouterUser();
return instancia;
};
same is the repository where the whole code is
https://github.com/proxirv/Socket.io-router
socket is a temporary object that exists only for the duration of one particular client connection. And, there can be zillions of them (one or more for each connected client). As such, you don't just export one socket or stuff it in a global and try to use that everywhere.
So, if what you're trying to do is to access the socket.io connection for the user that you just received an http request for, that's a bit more complicated and there are several different ways to approach it.
One approach, I've used before is shown below:
const express = require('express');
const app = express();
const server = app.listen(80);
const io = require('socket.io')(server);
const expsession = require('express-session');
const path = require('path');
// install session middleware
const sessionMiddleware = expsession({
secret: 'random secret',
saveUninitialized: true,
resave: true
});
// run session middleware for regular http connections
app.use(sessionMiddleware);
// run session middleware for socket.io connections
io.use(function(socket, next) {
sessionMiddleware(socket.request, socket.request.res, next);
});
// when a socket.io connection connects, put the socket.id into the session
// so it can be accessed from other http requests from that client
io.on('connection', function(socket) {
// socket.handshake.headers
console.log(`socket.io connected: ${socket.id}`);
// save socket.io socket in the session
console.log("session at socket.io connection:\n", socket.request.session);
socket.request.session.socketio = socket.id;
socket.request.session.save();
});
// any arbitrary express route definition
// Note: you can't send socket.io data in a request that loads an HTML page
// because that client hasn't yet established the socket.io connection
// for that page. The socket.io connections will be created after
// the browser loads this page.
app.get("/", function(req, res) {
const session = req.session;
console.log("\n\npage load\n---------------------------\n");
console.log("session:\n", session);
res.sendFile(path.join(__dirname, "socket-io-session.html"));
});
// Upon an API call from a page that already has a socket.io connection,
// respond to the API call and send something to that page's socket.io socket
app.get("/api/test", function(req, res) {
const session = req.session;
io.sockets.connected[session.socketio].emit('show', "sending some data");
console.log("session:\n", session);
console.log("session.socketio:\n", session.socketio);
res.json({greeting: "hello"});
});
Here are the steps in that concept:
Set up express-session for regular http connections. This gives you a place to store stuff that belongs to one particular client (keyed by a cookie)
Set up express-session for the socket.io connection so you can also have access to express-session data in socket.io connections.
When a socket.io connection happens, store the socket.id in the sesssion. This makes the socket.id available for future http requests from that specific client
When some future http request comes in from that client, you can reach into the session, get the socket.id value (which is just a string) and then use that to get the socket for that user and once you have the socket, you can use socket.emit() to send data just to that user.
If you didn't have other reasons for using express-session, you could also just put the socket.id into a cookie all by itself when the socket.io connection connects and then get the socket.id from the cookie during your http request.

node.js - Hosting server on public IP with socket.io

Consider the server code:
express = require('express');
app = express();
app.use('/', express.static(__dirname + '/'));
http = require('http').Server(app);
io = require('socket.io')(http);
...
http.listen(80);
I have also tried http.listen(80, "::").
And the client code:
socket = io();
This leads to the following console error when entering http://[#PUBLIC_IPv6_OF_SERVER]:3000 in the browser:
ERR_NAME_NOT_RESOLVED
How can I successfully enable clients to connect to the server through its public IPv6 address?
You need to allow cross origin request on server side.
var domains = "http://localhost:*";
io = require('socket.io')(http, {origins:domains});

using https with express io

So I am new to express and io but I had a server running fine for webRTC but now there is a deprecated method in webRTC that only runs on https so I tried to create an https server but it starts and then immediately exits. I cannot figure out what is wrong and I do not get any errors. Also I am using an aws ec2 to run the express io server. Maybe someone can spot where in my syntax/implementation I am going wrong.
Note I have been googling around for the past half hour and cannot figure it out
Here is the code:
var connect = require('connect');
var https = require('https');
var fs = require('fs');
var express = require('express.io');
var app = express();
//app.http().io();
var PORT = 443;
var options = {
key: fs.readFileSync('../server.key'),
cert: fs.readFileSync('../server.crt')
};
app.https(options).io();
//var app = https.createServer(options, app1);
console.log('server started on port ' + PORT);
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res){
res.render('index.ejs');
});
app.listen(PORT);
app.io.route('ready', function(req) {
req.io.join(req.data.chat_room);
req.io.join(req.data.signal_room);
app.io.room(req.data).broadcast('announce', {
message: 'New client in the ' + req.data + ' room.'
})
})
Update
I am putting a bounty on this because I would like someone to provide me with a complete answer on setting up the server for production.
You need to add a rule for port 443 in a Security Group for your instance.
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/authorizing-access-to-an-instance.html might help.

Sending cookie from server to browser using express

I am a computer science student and have been working on login with express.js for hours on XAMPP but couldn't find solutions. Here's my idea.
A user types userid and password and sends it through the server using jquery post method. Then, the server will check if id and password match and will send a temporary cookie storing the userid so the browser knows who or status signed in. However, I can't send this cookie to the browser from the server. I would really appreciate your input on this code or my idea.
// Variables
var portNum = 3000;
var express = require('express');
var app = express();
var http = require('http');
app.post('/login',function (req, res) {
console.log("LOGIN");
res.cookie('test', 'testValue');
res.send();
})
var server = app.listen(portNum, function () {
var host = server.address().address;
var port = server.address().port;
console.log("Example app listening at http://%s:%s", host, port)
})

Categories

Resources