Tuesday, February 13, 2018

How to emit socket.io event from express route

To demonstrate emitting socket.io event inside express route ,
we will  create a chat application first & them from our express route we will emit clear event to all chats on client.

lets start with creating express.js app.

first install express generator

npm install express-generator -g

then

mkdir xpress002
cd xpress002

we will use express generator to create boilerplate code as

    express -e

 now install socket.io  package  as
    npm install socket.io --save

Creating client  involve creating view & javascript to connect to socket.io from client side & displaying it on html also we need to serve our view through route.

a) inside views create socketclient.ejs with following content

            <html>

            <head>
                <title>Real time web chat</title>
                <script src="/socket.io/socket.io.js"> </script>
                <script src="/static/javascripts/code.js"></script>
            </head>

            <body>

                Name:
                <input type="text" name="name" id="name" style='width:350px;' /><br/>
                Message:
                <input type="text" name="field" id="field" style='width:350px;' /><br/>

                <input type="button" name="send" id="send" value="send" />
                <div id="content" style='width: 500px; height: 300px; margin: 0 0 20px 0; border: solid 1px #999; overflow-y: scroll;'>

                </div>
                <input type="button" name="clear" id="clear" value="clear" />
            </body>

            </html>

b) inside public/javascripts create code.js as follows

    window.onload = function () {

        var messages = [];
        var socket = io.connect('http://localhost:3000');

        var field = document.getElementById("field");
        var sendButton = document.getElementById("send");
        var content = document.getElementById("content");
        var name = document.getElementById("name");
        var clearButton = document.getElementById("clear");

        socket.on('warmup', function (data) {
            messages = [];
            if (data.message) {
                messages.push(data);
                var html = '';
                for (var i = 0; i < messages.length; i++) {
                    html += '<b>' + (messages[i].username ? messages[i].username : 'Server') + ': </b>';
                    html += messages[i].message + '<br />';
                }
                content.innerHTML = html;
            } else {
                console.log("There is a problem:", data);
            }
        });

        socket.on('cleanup', function (data) {
            messages = [];
            content.innerHTML = '';     
        });

        socket.on('message', function (data) {
            if (data.message) {
                messages.push(data);
                var html = '';
                for (var i = 0; i < messages.length; i++) {
                    html += '<b>' + (messages[i].username ? messages[i].username : 'Server') + ': </b>';
                    html += messages[i].message + '<br />';
                }
                content.innerHTML = html;
            } else {
                console.log("There is a problem:", data);
            }
        });

        sendButton.onclick = function () {
            if (name.value == "") {
                alert("Please type your name!");
            } else {
                var text = field.value;
                socket.emit('send', { message: text, username: name.value });
            }
        };

        clearButton.onclick = function () {
            socket.emit('cleanup', {});
        };

    }

c) inside bin/www file just below
        var server = http.createServer(app);
   add

        var io = require('socket.io').listen(server);
        app.io = io;//to let io accessible in router object
        io.on('connection', function (socket) {
        socket.emit('warmup', { message: 'welcome to the chat using socket.io' });

        socket.on('send', function (data) {
        io.sockets.emit('message', data);
        });

        socket.on('cleanup', function () {
        io.sockets.emit('cleanup', '');
        });
        });

d)  inside routes  add socket.js with following content

        var express = require('express');
        var router = express.Router();
        var path = require('path');

        router.get('/foo', function (req, res) {
            req.app.io.sockets.emit('cleanup', {});
            res.end()
        });


        router.get('/socketclient', function (req, res) {
        res.render('socketclient')
        })

        module.exports = router;

e) inside  app.js in root folder of application of express app make sure static point to public folder as
        app.use('/static', express.static(path.join(__dirname, 'public')));

        and route defined for socket included as  

        var socket = require('./routes/socket');
        app.use('/socket', socket);

my app.js file looks like

        var express = require('express');
        var path = require('path');
        var favicon = require('serve-favicon');
        var logger = require('morgan');
        var cookieParser = require('cookie-parser');
        var bodyParser = require('body-parser');

        var index = require('./routes/index');
        var users = require('./routes/users');
        var socket = require('./routes/socket');


        var app = express();

        // view engine setup
        app.set('views', path.join(__dirname, 'views'));
        app.set('view engine', 'ejs');

        // uncomment after placing your favicon in /public
        //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
        app.use(logger('dev'));
        app.use(bodyParser.json());
        app.use(bodyParser.urlencoded({ extended: false }));
        app.use(cookieParser());
        app.use('/static', express.static(path.join(__dirname, 'public')));

        app.use('/', index);
        app.use('/users', users);
        app.use('/socket', socket);


        // catch 404 and forward to error handler
        app.use(function (req, res, next) {
        var err = new Error('Not Found');
        err.status = 404;
        next(err);
        });

        // error handler
        app.use(function (err, req, res, next) {
        // set locals, only providing error in development
        res.locals.message = err.message;
        res.locals.error = req.app.get('env') === 'development' ? err : {};

        // render the error page
        res.status(err.status || 500);
        res.render('error');
        });

        module.exports = app;

Run express app with

        DEBUG=xpres002:* npm start


Now to test socket.io chat application open below url in two tabs

    http://localhost:3000/socket/socketclient

    add some stuff inside name & message textbox and click 'send'.Message is delivered to both window,try it few times.now in third tab hit

    http://localhost:3000/socket/foo

    you will see both chat client message history is cleared.

No comments:

Post a Comment