How to use Express with Socket.io? - node.js

I have the Express code in server JS file:
app.post('/confirm', function (req, res) {
// Here I need to send socket with emit()
});
Below mentioned code I have Socket.io:
io.on('connection', function (client) {
// All methods
});
Problem is that I can not get access to socket in express method app.post() and can not send data by POST action.
How can I use that?

You can emit data to specific connected sockets using the following:
io.to(socket_id).emit('something', {"bar":"foo"});
The "socket_id" variable is, as probably guessed, the socket.id from the connected socket.
You will probably have to store them along with some other identification in an array or object to send data to the correct clients later using express routes.
PS: As your code is
io.on('connection', function (client) {
// All methods
});
you would use client.id to get the socket id.

Related

What is 'socket' parameters in io.on()

I'm learning Socket.io with node js ,express
In this code :
io.sockets.on('connection', function (socket) {
console.log('Log !');
});
What it's use the parameters socket in this function ?
Thanks.
The socket parameter gives you information about the connected client, such as the unique socket.id which will help you send events to that specific socket, you can see in what rooms the socket is in, you can get information about the browser and more, you can inspect it with console.log(socket) and see a lot of information that you can use

Socket.io client specific variable

How do I store session specific info in Socket.io?
var client={}; //is this static across all sockets (or connected clients) that are connected?
io.on('connection', function(socket){
client.connectiontime=Date.now();
});
//on another io.on('connection') for the same connected client
io.on('connection', function(socket){
store(client.connectiontime);
}
How do I use the client variable only for the operations related to the currently connected client if it is considered static?
First, each socket is given a name that can be used to refer to it, but that changes each time the same client connects so this would not be useful if it is supposed to remain after the client leaves. If your goal is to store the connection time somewhere (a database?) then you would have to get a unique identifier from the client that could be used to find them again similar to a login. You would then pass the date object into the function that handles storing that time.
You should note though, that 'connection' is only called the first time the socket connects. A connection is not the event you normally would be using for when a client does something unless they disconnects between each access of the server program.
If you are sure you want to just use the Client object, you would likely have to create a client array and use the socket id as a key to access the object later. You would then have something like
array[socket.id].connectiontime = Date.now()
var client={}; //is this static across all sockets (or connected clients) that are connected?
var clients = [];
io.on('connection', function(socket){
clients[] = {
id : socket.id
connectiontime : Date.now()
}
});
//on another io.on('connection') for the same connected client
io.on('connection', function(socket){
// Here you would search for the object by socket.id and then store
store(client.connectiontime);
}

How do I emit data over socket io every time the database is updated?

I am building a system where I have a standalone administrative dashboard with a client interface. The front end is built on angularjs, and I'm using a boilerplate Node.js/Express server on the backend, which I have connected to a MySql database.
Every time a client submits new information from the client interface, it is submitted to the server, routed by the router to a controller, which passes the data to a model and uploads it to the database.
What I would like to do is every time the controller is called that handles the request, after the request has completed, I want to emit the new data over socket.io to the administrative dashboard.
My challenge is I have no idea how to access the socket from within the controller??? Any help would be greatly appreciated!
Yeah it's tricky. Like Express, Socket.io a request handling library of its own. They both work separately and independently, so there's no easy way to "switch" from Express to Socket.
However if you can identify a client uniquely, you can store its socket.id somewhere and then you can use the io from your Express controller to emit to that client's socket.
You can do io.to(socket.id).emit which is same as socket.emit, so as long as you have socket.id you can emit to it using io which is globally available.
I use Passport authentication in most apps so I find that using req.user is a great way to uniquely identify a client. It can even be a behind-the-scenes "pseudo" authentication by generating random userid/pass for each client.
Then there's this passport.socketio module to Access passport.js user information from a socket.io connection. Here's an article from the author that goes into the details of it all.
Using them together you can use the user object to store and access socket.id and use it to communicate to the client via socket.io
io.on('connection', function(socket){
var user = socket.request.user; // from socketio.passport
// store the socket.id inside the user so it can be retrieved from Express
user.socketid = socket.id;
});
app.post('/form', function(req, res, next){
var user = req.user; // from Passport
var socketid = user.socket.id // from socket above
var data = req.body;
doStuff(data);
io.to(socketid).emit('done');
});

How to use socket.io in app route

I develop my first project with nodejs. I use express 3 as framework and socket.io for the client server communication. At the moment I’m trying to create a register form. It works quite well, but I’m not sure how to use socket.io and express together correctly.
I check if the email and the password are valid, if they are not, I would like to push a json object the client.
I use this app route:
app.post('/user', function (req, res) {
var user = new User(req.body.user),
errors;
function userSaveFailed() {
res.render('index');
}
errors = user.validation(req.body.user.confirm);
user.save(errors, function (err) {
if (err) {
// Here I would like to send the Object to the client.
io.sockets.on('connection', function (socket) {
socket.emit('registration', {
errors : errors
});
});
return userSaveFailed();
}
res.render('user/new.jade');
});
});
Well, the client gets the json object, but if another client connects to '/' he also gets the object. I guess I use the socket.io wrong. What’s the common way to use a .emit() in an app route? Is it necessary to use a global authorization for socket.io and express for this test?
one way to do that (if you really want to use socket.io to reply to a post, which you probably shouldn't), is to use one room per user session.
so on the on("connection", ...) do something like so:
socket.join(room) where room is something unique to the session (like the session id for example).
then to send back to only one user:
socketio.of('/')['in'](room).emit(...);, room being that same unique id used above.

socket.io with express

i have a project and I'm using socket.io with express ,
so what i need (i tried) is broadcasting a message but from an express action.
is this possible i don't know how to get a reference to send or broadcast.
app.get('/', function(req, res) {
//i need to send messages from here
});
Other things like using both express+socket.io is working with me :)
As long as I understand,
Why not use the socket message type as an event instead of a http get or post? On the client side you would send a message via the websocket with let's say an event property.
So in your case:
<script>
// Initialize socket.io ...
// and then
socket.send({event: 'homepage loaded', foo: 'bar'});
</script>
And on the server side:
var io = io.listen(server);
io.on('connection', function (client) {
client.on('message', function (message) {
if (message.event == 'homepage loaded') {
client.broadcast(...);
}
});
});
You might want to have a look at my socket.io + Express primer. What you want is covered in detail there.
// Send to all connected sockets
io.sockets.send('Hello, World!');
// Send to all sockets in a specified room
io.sockets.in('room').send('Hello, Room!');
Where io is the value returned by the call to socketio.listen(). You can place that code anywhere in your application, eg in your app.get callbacks.
Check out my example repo where I use ExpressJS + Juggernaut(pubsub over socket.io):
http://github.com/shripadk/express-juggernaut-demo
This might be overkill for what you need as it uses Publish/Subscribe. But it does, to a certain extent, solve your issue of using regular ExpressJS routes. Checkout the master branch after cloning the repository:
git checkout master
I Found a nice example how to make what i need but with faye it's here http://nodecasts.org/.
I don't know the difference between Juggernaut ,Faye and direct Socket.io but Faye is good
for my case .And i think both of them use Socket.io internally.

Resources