How to use Express post request to emit Socket.io or Sockjs?

user1045217 picture user1045217 · Feb 23, 2012 · Viewed 32.9k times · Source

I know this question is kind of awkward, but the problem comes from Samsung TV 2010 / 2011 SmartTV (and blue ray player; of course 2012 emulator working fine). I ported the simple chatting examples come from the source and package to SmartTV app. Both of them fall back to JSONP polling, but from SmartTV app only could emit / push to server once. Receiving the message from server could be multiple times without any problem. After looking for the answer in Samsung D forum (of course nothing there), I think the fastest way to work around this issue is to deploy an Express server, taking the post data and JSON.parse, then emit Socket.io / Sockjs internally inside the server itself.

Could anybody show me an easy sample code so I could start from there? Thanks a lot.

I quickly make code, but seems it doesn't work:

lib/server.js

var express = require('express')
  , app = express.createServer()
  , io = require('socket.io').listen(app);

app.listen(80);

app.use(express.bodyParser());

app.get('/', function (req, res) {
  res.sendfile('/var/www/mpgs_lite_v3/index.html');
});

app.post('/', function(req, res){
  console.log(req.body);
  io.sockets.emit('my other event', req.body);
  res.redirect('back');
});

io.sockets.on('connection', function (socket) {
  //socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});

index.html

<html>
<head>
<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io.connect('http://localhost');
  socket.on('news', function (data) {
    console.log(data);
    socket.emit('my other event', { my: 'data' });
  });
</script>
</head>
<body>
<form method="post" action="/">
     <input type="hidden" name="_method" value="put" />
     <input type="text" name="user[name]" />
     <input type="text" name="user[email]" />
     <input type="submit" value="Submit" />
 </form>
</body>
</html>

'my other event' seems not receive anything.

Answer

Linus Thiel picture Linus Thiel · Feb 23, 2012

UPDATE: I updated the example for you to make it more complete. I didn't have an app.listen before, and here is also a client side script which shows that it, indeed, works fine:

<!doctype html>
<html>
    <head>
        <script src="//www.google.com/jsapi"></script>
        <script src="/socket.io/socket.io.js"></script>
        <script>google.load("jquery", "1.7.1")</script>
        <script>
            var socket = io.connect("localhost", {port: 3000});
            socket.on("foo", function(message) { console.log("foo: ", message) });
            $(function() {
                $("button").click(function() {
                    $.post("/foo", { message: $("input").val() });
                });
            });
        </script>
    </head>
    <body>
        <input type=text>A message</input>
        <button>Click me!</button>
    </body>
</html>

And the server, now with an app.listen directive:

var express = require("express"),
    app = express.createServer(),
    io = require("socket.io").listen(app)
    index = require("fs").readFileSync(__dirname + "/index.html", "utf8");

app.use(express.bodyParser());

app.get("/", function(req, res, next) {
    res.send(index);
});

app.post("/foo", function(req, res, next) {
    io.sockets.emit("foo", req.body);
    res.send({});
});

app.listen(3000);

Usage:

node app.js

Navigate to http://localhost:3000/ and click the button. Check your console for output.