I am working on a socket.io project in which I need to emit an event when the / page is requested. But all my routings are in a separate file router/index.js. Now, I want to emit a socket event on the page request from the router file.
I can't find a way to sort this out. Can anyone help?
put your socket object in separate file and export it.
//let io.js
var http = require('http').Server(app);
var io = require('socket.io')(http);
module.export.io = io;
now in route/index.js;
var io = require('io.js')
app.get('/', function(req, res){
io.sockets.emit('home.accessed');
})
simlarly if socket code was in server.js
require it from io.js likewise.
Related
I'm been looking around everywhere for the last few days for a way to access my socket IO instance running in Express from my routes and have not found a working solution.
The problem here is that I only run my socket IO instance at run-time and my routes and defined before that obviously.
The most promising solution I have found is one that wraps my routes in a function and requires it in my app.js file with whilst passing in the IO instance as an argument like so var routes = require('routes')(io)
Here is my setup:
app.js
const express = require('express');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
io.on('connection', function(client) {
console.log(io.sockets.sockets)
});
app.set('port', 7777);
const routes = require('./routes/index')(io);
app.use('/', routes);
app.listen('7777');
routes.js
module.exports = function(io) {
const express = require('express');
const router = express.Router();
router.get('/test', (req, res) => {
console.log(io.sockets.sockets);
});
return router;
}
If I connect to the WebSocket, my io.on event fires and I get a console log of the connected sockets in the form of a fairly large object that contains the socket id's etc.
If however, I get to the route '/test' I get a console log of a blank object: {}. I would imagine this is because the instance of the socket I am passing down to the routes does not have anyone connected to it at the time hence the blank object is returned, but this is just my best guess.
Where I'm a little stuck is how to get the full instance with all live connections to the route.
Alternatively, I've thought of attaching the io instance to the request object like so in order to have access to it in the routes:
server.on('request', function(req, res){
req.io = io;
}
but couldn't quite get it to work, nor am I sure this is the correct approach.
I imagine this must be a common issue so I would love a clear answer on how to work around this and the correct approach to tackle the issue.
EDIT
So I eventually got my above code working, I hit the '/test' endpoint from an AJAX GET request within the chrome extension instead of my just visiting the URL localhost:7777/test. What I can't understand here is why it works with an AJAX request but not page navigation? (The page navigation is done after I make the socket connection in the extension)
This code runs in the server. I am making a simple websocket on the server and it looks for connections made to it. However, IntelliJ does not recognize the on() method that has been called on io. I am using IntelliJ latest version and coding in Node.js
var http = require('http');
var express = require('express');
var socket = require('socket.io');
function onRequest(req,res)
{
console.log('User requested for page: ',req.url);
}
// create a middleware application
var app = express();
app.use(onRequest);
// serve static files
app.use(express.static('public'));
var server = http.createServer(app).listen(4000);
// setup the socket on the server
var io = socket(server);
io.on('connection',function(socket)
{
console.log('Socket id is: ',socket.id);
});
Try npm install #types/socket.io. It will add the necessary definition file.
I have laid out my project to look like the following
io.js
var io = require('socket.io')();
var socketioJwt = require('socketio-jwt');
var jwtSecret = require('./settings').jwtSecret;
io.set('authorization', socketioJwt.authorize({
secret: jwtSecret,
handshake: true
}));
io.on('connection', function(socket) {
});
module.exports = io;
app,js
var io = require('./io');
...
var server = http.createServer(app);
io.attach(server);
server.listen(33666);
Now I want to use the sockets in another script in order to send messages to the connected users like so:
script.js
var io = require('./io');
...
io.emit(event, msg);
My problem is that when I log io.sockets.connected inside script.js it always returns as an empty object. I have narrowed down my problem, and I believe this is happening because when requiring the io module inside script.js, io.js is running again and therefore I am instantiating a new io object.
Any idea how can I overcome that problem?
Thanks.
Your app.js file is the one that initializes your socket server, therefore you have to require it in script.js file:
var io = require('./io');
require('./app');
...
io.emit(event, msg);
BTW, node caches all requires, so you suspicion about node "running again" your io.js file is actually not true - the only thing that the second call to require('./io') does is returning your io instances reference.
var http = require("http").Server(express);
var io = require("socket.io")(http);
server.listen(8080);
Above code work if I put in different route. But how to create an instance of it so that I don't have to declare many times?
you are not clear with your question but i think you want to you io object in different files
you can do this using
app.all("*",function(req,res,next){
req.io=io;
next();
});
define this middleware before the routing in you server file
and where you want to use this you can get this object as
function(req,res,next){
var io = req.io;
}
New to node, so my apologies.
I'm working on my app and I want to send the location using socket.io. I've found 1000 examples, but all refer to when express had no routes, and it all was at the app.js. All examples refer to chat applications.
I was able to run an example piecing together several questions I searched but, I don't understand how to get the io that I finally got working on my app.js to interact with my index.js so I can use it with multiple emit parameters. express.io is outdated and I can't find anything current.
On bin/www
/**
* Socket.io
*/
var io = app.io
io.attach( server );
My app.js
var socket_io = require('socket.io');
var app = express();
var io = socket_io();
app.io = io;
So I can use:
io.on('connection', function (socket) {
console.log('IO Ready');
});
I don't know how to use the sockets on my index.js (routes), I can't modularize it.
Thanks in advance.
I have to say, I think the default generated project is bad for a socket.io setup. The node http.Server var is all the way in bin/www and not in app.js.
So the first thing is to move all the relevant stuff from bin/www to app.js. Mainly you just need
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
just like in the socket.io docs.
Now with io in app.js, we can use that when the routes are required. I forgot how exactly the default routes are set up, but I think they set up an app and just export it. Instead, you can set up something like
module.exports = function(app, io) {
io.on('connection', function(socket) {
console.log('connected!');
}
app.get('/foo', function() {
...
}
}
And now when you require the routes, instead of having the default
var index = require('./routes/index');
app.use(index);
or something of that accord, you can just do
require('./routes/index')(app, io);
And that's how you get io into your routes. Or at least how I do it anyway.