【问题标题】:Raspberry + socket.io works on local network but not from outsideRaspberry + socket.io 可以在本地网络上工作,但不能在外部网络上工作
【发布时间】:2015-02-14 22:50:14
【问题描述】:

我有一个 Raspberry Pi 通过 server.js 文件提供 html 页面。主要行(不是所有代码)是:

var app = require('http').createServer(handler);
var io = require('socket.io').listen(app);
...
app.listen(8000);
...
fucntion handler(req,res) {
  fs.readFile(__dirname+'/../index.html' function(err,data) {
...
io.sockets.on('connection', function (socket) {
  setInterval(function(){
  ...
  socket.emit('tempUpd',date,temp);
}, 2000);
});

在 index.html 上:

<head>
...
<script src="/socket.io/socket.io.js"></script>
...
</head>
<body>
<div id="info"></div>
---
<script>
var socket = io.connect('http://192.168.1.6:8000');

socket.on('tempUpd', function(date, temp){
   document.getElementById("info").textContent = temp;
});
...
</script>
</body>
</html>

如您所见,我们的想法是每 2 秒更新一次温度测量值。

当我通过本地网络(使用无线)从智能手机连接到我的 Raspberry PI 时,一切正常,我可以访问网页并查看每 2 秒变化一次的温度值。

当我关闭智能手机上的无线并通过移动网络连接到树莓派时(已将我的路由器配置为允许连接传递到树莓派),我可以看到网页,但所有信息都通过了套接字永远不会显示。

考虑到由于某种原因我无法在该页面上看到动态元素,我添加了另一个,并添加了一些代码,以便它使用 setInterval 每 2 秒显示一次当前时间。我看到时间在变化,但没有任何通过套接字显示的内容。再次,我切换到本地网络,一切都是可见的,包括通过套接字传递的信息。

对可能发生的事情有任何想法吗? 非常感谢!!

【问题讨论】:

    标签: node.js sockets websocket socket.io raspberry-pi


    【解决方案1】:

    192.168.1.6 是本地网络地址。您无法从本地网络外部访问该地址。移动网络在您的本地网络之外。当您通过手机使用 WiFi 时,您将连接到本地网络中的接入点,然后您可以路由到 192.168.1.6

    要从公共移动网络(从您自己的本地网络外部)访问它,您必须有一个从本地网络外部路由到您的服务器的公共 IP 地址。

    解决此问题的常用方法是为您的 Internet 连接获取公共 IP 地址(或使用动态 DNS 作为 DHCP 分配的地址),然后在您的 Internet 路由器上配置“端口转发”。这将接收发往您公共 IP 地址上特定端口的传入数据包,并将它们转发到您内部网络上的特定设备(例如您的 Raspberry Pi)。

    【讨论】:

    • 谢谢你的回答,但是192.168.1.6地址不是只用来server.js和index.html通信的吗?并且两者都在同一台机器上,它不应该工作吗?
    • @FilipeSim - 该地址用于从浏览器到服务器的通信,需要从浏览器所在的任何网络解析。 192.168.x.x 地址是所谓的私有地址(不用于公共网络)。请参阅Private Neworks 了解更多信息。
    • @FilipeSim - 也许这可能会有所帮助。 index.html 文件可能托管在服务器上,但它是由浏览器下载的,然后在浏览器中实际执行。因此,当它尝试连接到服务器时,它必须能够从浏览器所在的网络连接到服务器。
    • @FilipeSim - 由于您可能是新来的,您知道吗,如果您的问题得到了回答,那么您可以通过单击该答案左侧的绿色复选标记来选择最佳答案。这将向社区表明您的问题已得到解答,并且将在此处为您和提供答案的人在网站上赢得一些声誉积分,以遵循正确的程序。
    • 我(真的)是新人! :) 不仅在stackoverflow,而且在使用网络技术进行编程。非常感谢您的回答。现在想起来,我觉得自己很傻。那里有很多代码示例,但很少有人解释幕后发生的机制。再次感谢您的帮助!
    【解决方案2】:

    您需要更新 index.html 页面以根据节点服务器的 IP 地址动态打开您的套接字。正如其他人指出的那样,当您从 Internet 连接到服务器时,您的 Pi 不在 192.168.1.6。 (那是你的本地网络)

    如果您能够访问该网页,则说明您的路由器正在正确转发内容。

    在您的 index.html 页面上,将行从:

    var socket = io.connect('http://192.168.1.6:8000');
    

    到:

    var socket = io.connect('http://' + location.host + ':8000');
    

    还要确保将路由器上的端口 8000 也转发到 Pi。

    祝你好运。

    --埃德

    【讨论】:

      猜你喜欢
      • 2023-04-08
      • 1970-01-01
      • 2023-02-09
      • 2014-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多