Raspberry + socket.io适用于本地网络,但不适用于外部网络

时间:2015-02-14 22:50:14

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

我有一个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秒更改一次。

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

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

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

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

您需要更新index.html页面以根据节点服务器的IP地址动态打开您的套接字。正如其他人所指出的,当你从互联网连接到服务器时,你的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。

祝你好运。

- 埃德