2012-02-23 1 views
6

Je sais que cette question est un peu gênant, mais le problème vient de Samsung TV 2010/2011 SmartTV (et lecteur blue ray, bien sûr, l'émulateur 2012 fonctionne bien). J'ai porté les exemples simples de chat viennent de la source et du paquet à l'application SmartTV. Les deux se reportent à l'interrogation JSONP, mais à partir de l'application SmartTV, seule une émission peut être émise/envoyée au serveur une fois. Recevoir le message du serveur pourrait être plusieurs fois sans aucun problème. Après avoir cherché la réponse dans Samsung D forum (bien sûr rien là-bas), je pense que le moyen le plus rapide de contourner ce problème est de déployer un serveur Express, en prenant les données post et JSON.parse, puis d'émettre Socket.io/Sockjs en interne à l'intérieur du serveur lui-même.Comment utiliser la demande de publication express pour émettre Socket.io ou Sockjs?

Quelqu'un pourrait-il me montrer un exemple de code facile pour que je puisse commencer à partir de là? Merci beaucoup.

Je fais rapidement le code, mais il semble qu'il ne fonctionne pas:

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> 

mon autre événement »ne semble pas rien recevoir.

+0

J'ai trouvé la solution. le 'mon autre événement' à une autre fonction et laisser le message et l'émettre l'appellent Bien que ce problème résolve, j'ai besoin de gérer le socket qui est connecté sur l'autre ligne – user1045217

Répondre

12

MISE À JOUR: J'ai mis à jour l'exemple pour que vous le rendiez plus complet. Je n'ai pas eu app.listen avant, et voici également un script côté client qui montre que, en effet, fonctionne très bien:

<!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> 

Et le serveur, maintenant avec une directive app.listen:

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); 

Utilisation:

node app.js 

Accédez à http://localhost:3000/ et cliquez sur le bouton. Vérifiez votre console pour la sortie.

+0

merci, mais il semble ne pas fonctionner – user1045217

+0

J'ai mis à jour le –

+0

Linus, ce que j'ai essayé de faire est d'émettre quelque chose d'écrit dans le serveur (auto-émission, expresse post à socket.io émettre) .Power serveur au mécanisme client fonctionne très bien sur Samsung SmartTV (je voudrais disons StupidTV personnellement) Si je mets io.sockets.on ("foo", function (message) {// en envoie un autre au client ou simplement connecte la console} après app.listen (3000), il ne fera rien. – user1045217

2

Basé sur SockJS express example server.js pourrait ressembler à:

 
var express = require('express'); 
var sockjs = require('sockjs'); 

// 1. Echo sockjs server 
var sockjs_opts = {sockjs_url: "http://cdn.sockjs.org/sockjs-0.2.min.js"}; 

var sockjs_echo = sockjs.createServer(sockjs_opts); 
connections = {}; 
sockjs_echo.on('connection', function(conn) { 
    console.log(conn.id); 
    connections[conn.id] = conn 
    conn.on('close', function() { 
     delete connections[conn.id]; 
    }); 

    // Echo. 
    conn.on('data', function(message) { 
     conn.write(message); 
    }); 
}); 

// 2. Express server 
var app = express.createServer(); 
sockjs_echo.installHandlers(app, {prefix:'/echo'}); 

console.log(' [*] Listening on 0.0.0.0:9999'); 
app.listen(9999, '0.0.0.0'); 

app.get('/', function (req, res) { 
    res.sendfile(__dirname + '/index.html'); 
}); 

app.post("/send", function(req, res, next) { 
    for(var id in connections) { 
     connections[id].write('received POST'); 
    } 
    res.send({}); 
}); 

Pour tester le navigateur ouvert à localhost: 9999 et exécutez:

curl localhost:9999/send -X POST 
+0

J'apprécie votre travail. Cependant, votre exemple ne semble pas fonctionner de mon côté. 0. Je n'ai pas vu 'POST reçu' apparaître sur la console. 1. J'ai fait un simple client html (index.html) juste faire une demande de publication. A l'origine, je pensais que ça monterait sur localhost: 9999/echo/mais c'est sur localhost: 9999 /. 2. La même chose arrive sur un post lancé à partir de html. – user1045217

1

Je ne sais pas si cela aiderait, mais vous pouvez effectuer une abstraction d'émission sur le client en fonction de votre navigateur, puis créer une fonction get distincte sur le serveur qui traitera la requête de la même manière que le rappel socket.on. Afin de savoir où envoyer les informations je vous suggère d'utiliser une clé que vous pouvez stocker dans une table de hachage sur le serveur et dans le stockage local sur le client.

Pour le client:

var emit = function(event, options) { 
    if ("WebSocket" in window) { 
     socket.emit(event, options); 
     console.log("emited via WebSocket"); 
    } else { 
     $.post("http://localhost/emit/" + event, options); 
     console.log("emited via AJAX"); 
    } 
} 

emit("echo", { 
    key: localStorage.getItem("key"), 
    data: { 
     hello: "world" 
    } 
}); 

socket.on("response", function(data) { 
    console.log(data.hello); //will print "world" 
}); 

Pour le serveur:

var sockets = {}; 
var echo_handler = function(a) { 
    var socket = sockets[a.key]; 
    var data = a.data; 
    socket.emit("response", data); 
} 

app.post("/emit/:event", function(req, res) { 
    var event = req.params.event; 
    switch (event) { 
    case "echo": 
     var a = { 
      key: req.param("key"), 
      data: req.param("data") 
     } 
     echo_handler(a); 
     break; 
    } 
}); 

io.sockets.on("connection", function(socket) { 
    socket.on("connect", function(data) { 
     sockets[data.key] = socket; 
    }); 
    socket.on("echo", echo_handler); 
}); 

Une autre façon de faire sera de passer à Sockjs et d'utiliser leur patch.

Si quelqu'un a une meilleure solution pour Socket.IO il sera apprécié, parce que je suis déjà en profondeur dans le projet et il est trop tard pour passer Socket.IO pour Sockjs, et cette solution ne me plaît pas :(

Questions connexes