How to emit event with Socket.io and Node.js?

javascript, node.js, socket.io, websocket

Solution

It seems you need to emit an event from the server-side, this is possible and the main feature from socket.io.

To broadcast to all connected sockets use this code in the `/publish` endpoint:

` io.sockets.emit('event', data); `

Socket.io can also broadcast messages to group of sockets, this feature is called rooms.

If you want to send a message to only one socket, you can mark the sockets with an extra property when they connect and then search those sockets in the list of connected sockets.

Complete example:

Server side (server.js):

var http = require('http');
var fs = require('fs');

var server = http.createServer(handler);
var io = require('socket.io').listen(server);

function handler (req, res) {
  if (req.url === '/') {
    return fs.createReadStream(__dirname + '/index.html').pipe(res);
  }
  if (req.url === '/publish' && req.method === 'POST') {

    //this is what you are looking for:
    io.sockets.emit('super event', { message: 'hello' });
    //---------------------------------

    res.writeHead(200, {
      'Location': '/'
    });
    return res.end('');
  }
}

io.sockets.on('connection', function (socket) {
  socket.on('publish', function (data) {
    //if you need to emit to everyone BUT the socket who emit this use:
    //socket.broadcast.emit('super event', data);

    //emit to everyone
    io.sockets.emit('super event', data);
  })
});

server.listen(1080, function () {
  console.log('listening on http://localhost:1080');
});

Client side (index.html):

<html>
<head>
</head>
<body>
    hello world.
    <form action="/publish" method="post">
        <input type="submit" value="send a notification"></input>
    </form>

    <script src="/socket.io/socket.io.js"></script>
    <script>
      var socket = io.connect('/');
      socket.on('super event', function (data) {
        console.log(data);
        alert('got a message!');
      });
    </script>
</body>
</html>

Usage

- Put these two files in one directories.

- npm i socket.io

- node server.js

- open two tabs in the browser pointing to `http://localhost:1080`

- click the send notification button in one of the tabs

Problem

I find it hard to emit an event because I don't know much about creating an event/emitting an event with socket IO. Here is my problem on CASE "/publish": ``` var app = http.createServer(function (req, res) { if (req.method == "OPTIONS") { res.header('Access-Control-Allow-Origin', '*:*'); res.send(200); } else { var u = url.parse(req.url,true), body = ''; req.on('data',function(chunk) { body += chunk; }); req.on('end',function() { if(body) { var data =JSON.parse(body); if(data._app_secret && data._app_secret == 'nonexistent') { switch(u.pathname) { case '/generateusersecret' : findTokenByUser(req.headers.host+'_'+data.user_id,function(reply) { if(reply) { jsonResponse(res,{userSecret : reply}); } else { generateToken(req.headers.host + '_' + data.user_id,data.user_id,res); } }); break; case '/getusersecret' : findTokenByUser(req.headers.host + '_' + data.user_id,function(reply) { jsonResponse(res,{userSecret : reply}); console.log(reply); }); break; case '/publish': if(data.type == 'notification'){ var newData = { item_id : data.item_id, message : data.message, recipient : data.channel, itemLink : data.itemLink, timestamp : data.timestamp, read : 0 } notification = JSON.stringify(newData); // I need to emit my event here Socket.emit(THE EVENT HERE,notification DATA) } break; default: jsonResponse(res,{error : "Unknown Command: " + u.pathname}); break } } else { res.writeHead(403, {'Content-Type': 'text/plain'}); res.end('Not authorized'); } } }); } }); app.listen(config.port || 4000, null); ``` Then I need to listen on: ``` io.sockets.on('connection'function(socket){ socket.on('THE EVENT HERE',function(NOTIFICATION DATA){ //I NEED TO EMIT ANOTHER EVENT HERE }) }) ``` Is there a possible way for this? I have to do this because I am using PHP's cURL and I can't emit on client side so I need to emit it on server side.

Original source