Is there a way to host a Socket.Js server on Github? - javascript

const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
app.get('/', (req, res) => {
res.sendFile(__dirname + '/chat.html');
});
server.listen(8000, () => {
console.log('listening on *:8000');
});
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
io.on('connection', (socket) => {
socket.on('chat message', (msg) => {
console.log('message: ' + msg);
});
});
io.emit('some event', { someProperty: 'some value', otherProperty: 'other value' }); // This will emit the event to all connected sockets
io.on('connection', (socket) => {
socket.on('chat message', (msg) => {
io.emit('chat message', msg);
});
});
Currently it's localhost, and I have to run node index.js everytime I want to start it. But is there a way I can host it on GitHub so it always stays on?

Short answer: No.
GitHub hosts git repositories containing code, but doesn't run code. GitHub pages can serve static sites, but cannot run server side code, which include node.js and express. If you want to host something like this for free, I suggest looking into Heroku.

Related

ReferenceError: client is not defined Socket.io

How to solve this? I don't get it,,please help, thanks. And this is the error message when I run node server.js:
client.on('getRelay', function (state) {
ReferenceError: client is not defined
var express = require ('express');
var app = require('express')();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var port = 3000;
let bodyRelay = {
relayId: 'RELAY-123',
state: 1
}
app.use(express.static(__dirname + '/node_modules'));
app.get('/', function(req, res, next) {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(client) {
console.log('a user has connected');
});
io.sockets.emit('setRelay', bodyRelay);
client.on('getRelay', function (state) {
bodyRelay = state;
console.log('id: ' + client.id + 'bodyRelay: ' + JSON.stringify(bodyRelay));
// io.sockets.emit('setRelay', bodyRelay);
});
client.on('disconnect', function() {
console.log('a user has disconnected');
});
server.listen(port, () => {
console.log('Server is running on port: ' + port)
});
The blocks of code that reference client, must be inside this callback:
io.on('connection', function(client) {
console.log('a user has connected');
});
because that is where client is defined. Like this:
io.on('connection', function(client) {
console.log('a user has connected');
client.on('getRelay', function (state) {
bodyRelay = state;
console.log('id: ' + client.id + 'bodyRelay: ' + JSON.stringify(bodyRelay));
// io.sockets.emit('setRelay', bodyRelay);
});
client.on('disconnect', function() {
console.log('a user has disconnected');
});
});
A few other notes on your code.
The location you have this:
io.sockets.emit('setRelay', bodyRelay);
does not make any sense because you're calling it when you initialize the module which will NEVER have any connected socket.io clients so it will not do anything useful.
And, the way you are using the bodyRelay variable seems like a possible design error. You've made it a module-level variable which means it is shared among all request handlers for all connections. Unless this is intended to be something that all clients can change and all clients access the exact same set of data, then it perhaps needs a different design. I don't know what you're really trying to do with it to know what design to suggest.

Unable to connect to socket.io using express server

I'm trying to create WebSocket using the following code.
const express = require('express')
const app = express()
const http = require('http')
const server = new http.createServer(app)
const io = require('socket.io')(server)
const CONFIG = {
host: 'localhost',
port: 4444
}
io.on('connection', function (socket) {
const sid = socket.id
console.log('connection socket id:', sid)
for (const msg of ['disconnect', 'disconnecting', 'error']) {
socket.on(msg, data => {
console.log(`* ${msg}:`, data)
})
}
socket.on('join', data => {
console.console.log("data", data)
})
socket.on('signal', data => {
console.log('signal', data)
})
})
server.listen({
host: CONFIG.host,
port: CONFIG.port,
}, info => {
console.info(`Running on`, server.address())
})
When I try to test this using https://www.websocket.org/echo.html I'm receiving an undefined error.
I have given ws://127.0.0.1:4444 in the location field but when I try to connect I'm getting the following error in the Log:
ERROR: undefined
and in the message Connection closed before receiving a handshake response
What is wrong here how I can make this working?
Your server seems good, you should implement the client yourself.
Socket.IO server and client example from the documentation.
Server:
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', (socket) => {
socket.on('message', (msg) => {
console.log('message: ' + msg);
});
});
http.listen(3000, () => {
console.log('listening on *:3000');
});
Client (index.html):
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script>
$(function () {
var socket = io();
socket.emit('message', 'Test message.');
});
</script>

Socket.IO & Node/Express Configuration

I am trying to connect my front-end which is on a online text editor to my Node server. I am hitting network error strict-origin-when-cross-origin and it is not hitting the Socket IO listener. Please let me know what is causing this error & how to fix it. Thanks!
Here is the Node.js code:
const cors = require('cors');
const app = express();
app.options('*', cors())
app.all('*', function(req, res) {
res.send("Oops, incorrect URL")
});
const server = http.createServer(app).listen(process.env.PORT, () => {
console.log('Express server listening on port 1337');
});
var io = require('socket.io')(server);
io.set('origins', '*:*');
io.on('connection', function(socket){
socket.on('chat message', function(msg){
console.log('message: ' + msg);
});
console.log("CONNECTED!")
});
Here is the front-end:
import io from 'socket.io-client'
var socket = io('https://myserver.com/', {secure: true});
socket.emit('chat message', "testing");

I want to make multiple namespaces based on the URL but I'm confused socket.io

user can access namespace like nsp1 by hitting localhost:3000/nsp1
the same with nsp2, I want to create them dynamically with a name entered from text box
but for now I tried to make just one namespace using code below but the server hits error Cannot GET /my-namespace
server.js
var io = require('socket.io')(http, { path: '/my-namespace'});
io
.of('/my-namespace')
.on('connection', function(socket){
console.log('a user connected with id %s', socket.id);
socket.on('my-message', function (data) {
io.of('my-namespace').emit('my-message', data);
// or socket.emit(...)
console.log('broadcasting my-message', data);
});
});
client.js
var socket = io('localhost:3000/my-namespace', { path: '/my-namespace'});
server.js
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(3000);
app.get("/contact.html", function (req, res) {
res.sendfile(__dirname + '/contact.html');
});
app.get("/login.html", function (req, res) {
res.sendfile(__dirname + '/login.html');
});
app.get("/", function (req, res) {
res.sendfile(__dirname + '/home.html');
});
app.get(/(^\/[a-zA-Z0-9\-]+$)/, function (req, res) {
//Matches anything with alphabets,numbers and hyphen without trailing slash
res.sendfile(__dirname + '/room.html');
});
io.on('connection', function(socket){
console.log('a user connected with id %s', socket.id);
socket.on('join', function (room) {
//May be do some authorization
socket.join(room);
console.log(socket.id, "joined", room);
});
socket.on('leave', function (room) {
//May be do some authorization
socket.leave(room);
console.log(socket.id, "left", room);
});
socket.on('chat message', function (data) {
//May be do some authorization
io.to(data.room).emit("chat message", data.message);
});
});
room.html/client.js
var socket = io('localhost:3000');
socket.emit("join",location.pathname);
socket.emit("chat message",{room:location.pathname, message:<val>});

Socket.io trigger event from controller of HTTP API

In my Node+Express server app I'd like to emit notifications from specific controllers triggered by requests coming from the HTTP API:
For example:
router.route('/status').put(Order.changeStatus)
class Order {
static changeStatus(req, res) {
// Modifying database record with changed status
// Emiting message to specific socket room
}
}
I'm handling socket connections as follows:
import AuthMiddleware from '../middleware/AuthMiddleware';
const socketio = require('socket.io');
let io;
module.exports.listen = function(app){
io = socketio.listen(app);
io.on('connection', function(socket){
console.log('Client connected');
AuthMiddleware.authenticateSocket(socket, (err, user) => {
socket.join(user._id);
console.log('Client joined to: ' + user._id);
})
socket.on('disconnect', () => {
console.log('Client disconnected')
});
});
return io;
}
After authenticating the incoming socket connection, it is subscribed to the room of its own ID.
The socket is initialised at the top of the project as follows:
import app from './app';
import http from 'http';
const PORT = process.env.PORT || 7235;
const server = http.createServer(app);
const io = require('./socket/main').listen(server);
// App start
server.listen(PORT, err => {
console.log(err || `Server listening on port ${PORT}`);
});
Although I'm able to process incoming events and respond to those, the problem with this structure is that I can't access the io object within the controllers to be able to emit data in a particular room as follows:
io.sockets.in(userID).emit('notification', data);
What would be the proper structure that enables to trigger socket events from the controllers of the HTTP API?
Your controllers need to have access to the configured io object. The easiest way to do that is to export it in your module instead of just exporting the listen function, perhaps like so:
import AuthMiddleware from '../middleware/AuthMiddleware';
const socketio = require('socket.io');
let io;
function listen(app){
io = socketio.listen(app);
io.on('connection', function(socket){
console.log('Client connected');
AuthMiddleware.authenticateSocket(socket, (err, user) => {
socket.join(user._id);
console.log('Client joined to: ' + user._id);
})
socket.on('disconnect', () => {
console.log('Client disconnected')
});
});
return io;
}
module.exports = {
listen, io
}
Then your controllers can just do const io = require('./path/to/that').io;

Categories