socket.io with express - node.js

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.

Related

Using Node, Express, (and Socket.io?) to update a page every 1 second

I am a bit new to Node.js and Express, and am currently working on a page where I would like to generate and send messages (from the server) to the client page every 1 second (1250ms, actually). When a user visits the site, I would like the latest message to be broadcasted, with new messages coming in every second after. In other words, every user would see the same message at the same time on the web page, regardless of when they connected to the server.
I have done some searching and have unfortunately have not had any luck playing with code samples online. Here is a ROUGH IDEA to explain:
app.js
'use strict';
var express = require('express');
var app = express();
var http = require( "http" ).createServer( app );
var io = require( "socket.io" )( http );
app.get('/', function (req, res) {
res.sendFile(__dirname + '/public/index.html');
});
http.listen(3000, function(){
/* someFunction to generate new LATESTMESSAGE every 1s */
io.on('connection', function (socket) {
socket.emit('news', { messages: LATESTEMESSAGE })
});
});
I assume I would need to send the message via socket.io from the function that generates the LATESTMESSAGE (every 1s when message is generated, send via socket?)? If that is the case, I am unfamiliar with how I would require socket.io in a page that is NOT the app.js (this function would probably be a class, in its own js file), as socket.io requires app and express (see code above).
I appreciate the help! I have spent a good amount of time pondering this today and would appreciate any direction or assistance. Please let me know if I have not supplied enough information.
p.s. the code above definitely would not accomplish what is needed. just a rough outline to show what i am attempting to accomplish
What you're doing looks like half-duplex communication i.e. Only the server sends data to the client, and not the other way around. Socket.io is full duplex communication, i.e. Server and client send data to each other. So technically what would be best for your requirements is Server Sent Events (SSE) using EventStream. Socket.io might be slightly excessive.
Having said that, what you want is to write a Middleware, to which you pass the application. Please take a look at https://expressjs.com/en/guide/using-middleware.html
Basically, your io would be passed in to the middleware functions, so they'd have access to Socket. And the middleware functions in turn would be imported into your app.js.

How to use Express with Socket.io?

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.

Routing with socket.io

I'm writing an express app.js with socket.io, and came across a problem.
I can't figure out how to use the routes.
I want the client to write for example localhost:3000/?id=3 and get something according to the id.
But in the socket.io connection event I dont know the url or the params (or is there a way?)
io.on('connection', function (socket) {/*should be something according to the id in the url*/});
untill now I just checked the id with
app.get('/', function (req, res) {
//req.query.id
});
Anyone knows a way around this?
Thank you!
It appears you may be a bit confused about how you use webSockets. If you want to make an http request such as localhost:3000/?id=3, then you don't use webSockets. You use the normal routing mechanisms in Express.
A webSocket connection is created and then persists. From then on, you define messages with optional data as arguments for those messages and you can send these messages either direction on the webSocket. webSocket messages are sent on an existing webSocket, not to a URL. You could create a message for sending URLs from client to server if you wanted. If that was the case, you could do this in the client:
socket.emit("sendURL", url);
And, then you would listen for the "sendURL" message on the server.

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.

How to send a temporary chunk of html and js to a running app on node.js

I just got my first app up and running on Node.js. As of now, it is simply serving up a static file. But I have a few ideas that will be implemented down the road so I'm going ahead and getting Node setup so I'll be ready for it when that time comes.
// get modules
var express = require('express');
var fs = require('fs');
// create app instance
var app = express();
// static files middleware
app.use("/assets", express.static(__dirname + '/assets'));
// main route
app.get('/', function(req, res) {
var html = fs.readFileSync('assets/views/main.html', 'utf8');
res.send(html);
});
// make web server listen on specific port
app.listen(8080);
NOTE: I realize I don't need Express to serve one route, but I figured what's the harm in getting a head start on that as well?! :)
The first idea i had is to make a way to let all users currently using the app that there has been an update and that they must refresh their browser. There is no need to save the current state of the app as it is pretty basic.
So, if I am a user, I'm using the app and boom, I get a pretty little modal-window-alert-notification thingy letting me know that I need to refresh.
Also, if some user loads the app AFTER I have sent the alert, that user should not see the alert at all (because they should already be seeing the new changes).
I have done some googling on the subject and I'm just not satisfied with the examples i found. I do not think I want to have to update a notifications.xml file (which node.js would be watching) to push a new notification.
One solution I can think of would be to make a command that can be executed from the command line that will (somehow) send a new notification to the app. Perhaps using something like Grunt.js (I'm not sure if it would be a good fit for this as I've never used it). Basically, once the notification has been sent, all traces of it should disappear. That's why I think a command line approach would be good.
Here's my question: How (generally speaking) should I implement something like this? I am a Node.js newbie but I am pretty comfortable with javascript and the command line.
Please feel free to offer up any alternative solution you think would be better for me (other than a command line approach), or any tools that you think could help me.
Thanks!
If you want to push updates to a web client, one way is to use something like Socket.io. This creates a two-way pipe between client and server that you can use to asynchronously push updates through.
Sample server:
var app = require('express').createServer()
, io = require('socket.io').listen(app);
app.listen(80);
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
Sample client:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
alert('New news has come in! Please refresh your page!');
socket.emit('my other event', { my: 'data' });
});
</script>
The other option is to poll from the client using Javascript to actively look for updates. You would need to keep some state on the server for each client that would determine if that client required an update. The client would then make a get request on some timer interval (once a second, for example) to a secondary route and the server would reply with 'Yes, you need an update' or 'No, you don't need an update'. If yes, the client Javascript would then pop up your modal box and tell the user to refresh.

Resources