【问题标题】:How to use Express post request to emit Socket.io or Sockjs?如何使用 Express post 请求发出 Socket.io 或 Sockjs?
【发布时间】:2012-03-13 18:49:12
【问题描述】:

我知道这个问题有点尴尬,但问题来自三星电视 2010 / 2011 SmartTV(和蓝光播放器;当然 2012 模拟器工作正常)。我将简单的聊天示例从源代码和包移植到 SmartTV 应用程序。它们都回退到 JSONP 轮询,但从 SmartTV 应用程序只能发出/推送到服务器一次。从服务器接收消息可能多次没有任何问题。在三星 D 论坛中寻找答案(当然那里没有)后,我认为解决此问题的最快方法是部署 Express 服务器,获取帖子数据和 JSON.parse,然后在内部发出 Socket.io / Sockjs在服务器本身内部。

谁能给我看一个简单的示例代码,以便我可以从那里开始?非常感谢。

我很快就写代码了,但是好像不行:

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>

“我的其他活动”似乎没有收到任何信息。

【问题讨论】:

  • 我找到了解决方案。只需将“我的其他事件”中的任何内容移动到另一个函数,然后让 post 和 emit 调用它。虽然这个问题解决了,但我需要管理连接在其他线路上的套接字。

标签: node.js express socket.io samsung-smart-tv


【解决方案1】:

更新:我为您更新了示例以使其更加完整。我之前没有app.listen,这里还有一个客户端脚本,显示它确实可以正常工作:

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

还有服务器,现在有一个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);

用法:

node app.js

导航到http://localhost:3000/ 并单击按钮。检查控制台的输出。

【讨论】:

  • Linus,我试图做的是发出一些写在服务器上的东西(自我发射,快递到 socket.io 发射)。服务器推送到客户端机制在三星 SmartTV 上运行良好(我个人会说 StupidTV)。如果我在 app.listen(3000) 之后放置 io.sockets.on("foo", function(message) { // 向客户端发送另一个或只是登录控制台 }; 它不会做任何事情。
  • 对于较新版本的 express : var express = require('express') , http = require('http'); var bodyParser = require('body-parser'); var app = express(); var server = http.createServer(app); var io = require('socket.io').listen(server); server.listen(my_port);
【解决方案2】:

基于SockJS express example server.js 可能看起来像:

var express = require('express'); var sockjs = require('sockjs'); // 1. Echo sockjs 服务器 var sockjs_opts = {sockjs_url: "http://cdn.sockjs.org/sockjs-0.2.min.js"}; var sockjs_echo = sockjs.createServer(sockjs_opts); 连接 = {}; sockjs_echo.on('连接',函数(conn) { 控制台.log(conn.id); 连接[conn.id] = conn conn.on('关闭', function() { 删除连接[conn.id]; }); // 回声。 conn.on('数据',函数(消息){ conn.write(消息); }); }); // 2. 快递服务器 var app = express.createServer(); sockjs_echo.installHandlers(app, {prefix:'/echo'}); console.log(' [*] 正在监听 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){ 连接[id].write('收到 POST'); } res.send({}); });

在 localhost:9999 测试打开的浏览器并运行:

curl localhost:9999/send -X POST

【讨论】:

  • 感谢您的工作。但是,您的示例似乎对我不起作用。 0. 我没有在控制台上看到“received POST”。 1.我做了一个简单的客户端html(index.html)只是做一个post请求。最初我认为它会安装在 localhost:9999/echo/ 上,但它在 localhost:9999/ 上。 2. 同样的事情发生在从 html 启动的帖子上。
【解决方案3】:

删除这条评论 //socket.emit('news', { hello: 'world' }); 到 socket.emit('news', { hello: 'world' });

它会起作用,因为它通过新闻发出数据,并且您正在使用我的其他事件而不是“新闻”来收听,或者您可以使用“我的其他事件”来收听

【讨论】:

    【解决方案4】:

    我不知道这是否会有所帮助,但是您可以根据您的浏览器在客户端上进行一个发出抽象,然后在服务器上创建一个单独的 get 函数,该函数将以与 socket.on 相同的方式处理请求打回来。为了知道将信息发送到哪里,我建议您使用一些可以存储在服务器哈希表和客户端本地存储中的密钥。

    对于客户:

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

    对于服务器:

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

    另一种方法是切换到 Sockjs 并使用他们的patch

    如果有人对 Socket.IO 有更好的解决方案,将不胜感激,因为我已经深入该项目,现在为 Sockjs 切换 Socket.IO 为时已晚,而且这个解决方案不是我喜欢的 :( .

    【讨论】:

      猜你喜欢
      • 2020-10-22
      • 2020-10-21
      • 1970-01-01
      • 2022-10-12
      • 2017-11-30
      • 2015-11-26
      • 2018-05-04
      • 2014-06-20
      • 2019-09-28
      相关资源
      最近更新 更多