Package express-ws doesn't let clients connect - node.js

I have an express router defined for express-ws npm package. The router looks is exported like:
//ws.js
var express = require('express');
var router = express.Router();
var connections = {};
router.ws('/connect/', function (ws, req) {
// console.log(ws);
ws.on('close', function(x, y, z) {
console.log(a, b, c);
});
});
module.exports = router;
The (not all) statements in the express app are (and in order):
//app.js
var app = express();
var expressWs = require('express-ws')(app);
var index = require('./routes/index');
var ws = require('./routes/ws');
...
...
app.use('/ws', ws);
app.use('/*', index);
The server has statements like:
//bin/www - Generated by express generator
var app = require('../app');
var debug = require('debug')('server:server');
var http = require('http');
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
var server = http.createServer(app);
server.listen(port);
After I run it, I am not able to connect to /ws route over websocket. Am I missing something here? Is there a better way to create websocket running on Express 4?
This is the error I see at the client! What am I doing wrong?

changes to app.js
var app = express();
var server = require('http').Server(app);
var expressWs = require('express-ws')(app,server);
...
...
//module.exports = app;
module.exports = {app: app,server: server};
changes to bin/www
//var app = require('../app');
var app = require('../app').app;
...
...
//var server = http.createServer(app);
var server = require('../app').server;

I know this is old but here's the issue. HTTP server isn't required.
//app.js
const express = require('express');
const { app } = require('express-ws')(express());
const index = require('./routes/index');
const ws = require('./routes/ws');
...
app.use('/ws', ws);
app.use('/*', index);
...
app.listen(8080, () => console.log('Listening on port: 8080');

Related

Not able to connect socket.io in nodejs

Hi I am trying to setup a connection with socket.IO but not able to do so. At present I am not getting any error but the connection is not taking place.Please find below the relevant details :
app.js
const express = require('express');
require('./db/mongoose');
const functions = require("firebase-functions");
var bodyParser = require('body-parser');
const app = express();
const http = require('http').createServer(app);
var io = require('socket.io');
socket = io(http, {cors: {
origin: "http://localhost",
methods: ["GET", "POST"]
}
});
var cors = require("cors");
var cookieParser = require('cookie-parser');
var path = require('path');
app.use(cors());
const portCheck = process.env.PORT || 3001
socket.on('connection', function (socket) {
console.log('connected to socket');
socket.emit('greeting-from-server', {
greeting: 'Hello Client'
});
});
app.listen(portCheck, ()=> {
console.log('Server Listening to port:' + portCheck);
})
Changes should done for your code as follows:
Change app listen with server listen
wrap socket.on(//...) with io.on(//...)
replace this lines
const app = express();const http =
require('http').createServer(app);
with
var server = require('http').Server(app);
var io = require('socket.io')(server);
After the changes code is like follows.
const express = require('express');
require('./db/mongoose');
const functions = require("firebase-functions");
var bodyParser = require('body-parser');
const app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
socket = io(http, {cors: {
origin: "http://localhost",
methods: ["GET", "POST"]
}
});
var cors = require("cors");
var cookieParser = require('cookie-parser');
var path = require('path');
app.use(cors());
const portCheck = process.env.PORT || 3001
server.listen(portCheck, ()=> {
console.log('Server Listening to port:' + portCheck);
})
io.on('connection', (socket)=> {
socket.on('connection', function (socket) {
console.log('connected to socket');
socket.emit('greeting-from-server', {
greeting: 'Hello Client'
});
});
});
follow more information through this link. https://socket.io/get-started/chat.

Emitting and receiving events with Socket.io

I'm trying to emit an event with socket.io on my Node Js server and receive it client-side but I can't get it to work.
This is my server code:
// require our dependencies
var express = require('express');
var expressLayouts = require('express-ejs-layouts');
var bodyParser = require('body-parser');
var app = express();
var port = 3000;
var server = require("http").Server(app);
var io = require('socket.io')(server);
// use ejs and express layouts
app.set('view engine', 'ejs');
app.use(expressLayouts);
// use body parser
app.use(bodyParser.json({extended : true}));
// route our app
var router = require('./app/routes');
app.use('/', router);
// set static files (css and images, etc) location
app.use(express.static(__dirname + '/public'));
// start the server
app.listen(port, function() {
console.log('app started');
});
This is my routes.js code, where the magic should happen:
module.exports = function(io){
// require express
var express = require('express');
var path = require('path');
// create our router object
var router = express.Router();
// export our router
//module.exports = router;
router.post("/", function(request, response) {
console.log(request.body);
io.emit('getupdate',{hello:'world'});
});
// route for our homepage
router.get('/showevent', function(req, res) {
res.render('pages/showevent',{data:exportage});
});
return router;
}
While this is my client-side script:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost:3000');
socket.on('getupdate', function (data) {
console.log(data);
});
</script>
On the routes.js file, to get the "io" variable i wrapped all inside a function.
I can't get the message emitted in case of a POST request on my client.
Could you help me to find the issue here ?
Try this:
// require our dependencies
var express = require('express');
var expressLayouts = require('express-ejs-layouts');
var bodyParser = require('body-parser');
var app = express();
var port = 3000;
var server = app.listen(port);
var io = require('socket.io').listen(server);
I am not sure if you have updated this in your own code, but this snippet should pass io to the router:
// route our app
var router = require('./app/routes')(io);
app.use('/', router);

socket.io emit when someone call the API

I have a small project with NodeJS Express server and Angular2 frontend. The server has an API interfaces. The main part of this is: /api/alert. I want to do the following: If the /api/alert get an request then socket.io broadcast an event to all connected clients.
My server structure is the following:
server.js
var http = require('http'),
express = require('express'),
app = module.exports.app = express(),
port = process.env.PORT || 3000,
mongoose = require('mongoose'),
bodyParser = require('body-parser'),
db = require('./config/db'),
path = require('path');
mongoose.Promise = global.Promise;
mongoose.connect(db.url);
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'dist')));
var routes = require('./server/routes/index');
routes(app);
var server = http.createServer(app);
var io = require('socket.io')(server);
server.listen(port);
console.log('Server started on: ' + port);
server/routes/index.js
const deviceRoute = require('./devicesRoute');
const alertRoute = require('./alertsRoute');
module.exports = function(app) {
deviceRoute(app);
alertRoute(app);
}
server/routes/alertRoute.js
'use strict';
module.exports = function(app) {
var alertsService = require('../services/alertsService');
app.route('/api/alert')
.post(alertsService.createAlert);
};
server/service/alertService.js
'use strict';
exports.createAlert = function(req, res) {
// do something in database
// I want to broadcast to all client HERE
};
I can't pass the io and server variables to the function (from server.js). How can I do that? What is the easiest way?
Thank you!
First you would want to export both the app and server objects from server.js and pass your socket to your response in middleware as follows:
var app = express();
var server = http.createServer(app);
var io = require('socket.io')(server);
app.use(function(req, res, next){
res.io = io;
next();
});
...
module.exports = {app: app, server: server};
You can then require the server instance you created in server.js (depending on where you are requiring it from) as
var server = require('../server').server;
Since you added socket.io to the response object, you can use it in your services as
'use strict';
exports.createAlert = function(req, res) {
// do something in database
// I want to broadcast to all client HERE
res.io.emit("broadcast", "clients");
};

Error: Cannot GET /

I am working in c9.io ide environment, I have written below code in server.js file
var http = require('http');
var path = require('path');
var async = require('async');
var socketio = require('socket.io');
var express = require('express');
var express = require('express');
var app = express();
var router = express();
var server = http.createServer(router);
server.listen(process.env.PORT || 3000, process.env.IP || "0.0.0.0", function(){
var addr = server.address();
console.log("Server listening at", addr.address + ":" + addr.port);
});
app.use(express.static(__dirname + '/client'));
// respond with "hello world" when a GET request is made to the homepage
app.get('/', function(req, res) {
res.render('index.html');
});
app.get('/about', function (req, res) {
res.send('about');
});
After running node server.js in terminal the message given as
Your code is running at https://nodejs2-mujaffar.c9.io.
Important: use process.env.PORT as the port and process.env.IP as the host in your scripts!
Server listening at 0.0.0.0:8080
But after accessing https://nodejs2-mujaffar.c9.io/ url -- It is not rendering view only displaying message Error: Cannot GET /
What I am doing wrong?
Please help.
You seem to have created two instances of express which may be your problem.
Try changing:
var express = require('express');
var app = express();
var router = express();
var server = http.createServer(router);
to:
var express = require('express');
var app = express();
var server = http.createServer(app);
At the minute, your express app variable is not bound to your http server. You have instead bounded an unused instance called router. But then you have registered your routes to the app variable.

Socket.IO and express routes

I would like to use socket.io and express routes and I have the following code:
app.js
var
http = require('http'),
path = require('path'),
passport = require('passport'),
userpassport = require('./lib/strategies/local'),
githubpassport = require('./lib/strategies/github'),
flash = require('connect-flash'),
express = require('express'),
logger = require('morgan'),
bodyParser = require('body-parser'),
cookieParser = require('cookie-parser'),
session = require('express-session'),
errorhandler = require('errorhandler'),
csrf = require('csurf'),
favicon = require('serve-favicon'),
sockets = require('./lib/socket'),
app = express();
var routes = require('./routes')();
app.get('/', routes.index);
var server = http.createServer(app).listen(app.get('port'), function () {
var io = require('socket.io')(server);
io.on('connection', function (iosocket) {
sockets.setSocket(iosocket);
});
});
lib/socket.js
var socket;
exports.setSocket = function(iosocket) {
console.log('setting socket');
socket = iosocket;
}
exports.getSocket = function() {
console.log('getting socket');
return socket;
}
routes/index.js
var sockets = require('../lib/socket');
module.exports = function () {
var routes = {};
routes.index = function (req, res) {
var socket = sockets.getSocket();
socket.on('app/create', function (data) {
console.log('got app create');
});
}
This does not work, I think it's because the setSocket function that appears on app.js runs after the page was loaded, therefore when I getSocket on the route it's not the latest socket (I can console log the given socket on the route, I can see there's a socket there, but I can also see that the setSocket runs afterwards).
How can I solve this?

Resources