gpt4 book ai didi

javascript - Socket.io 客户端由于 ping 超时/传输关闭而断开连接

转载 作者:太空宇宙 更新时间:2023-11-04 01:46:57 28 4
gpt4 key购买 nike

这是我的设置:

树莓派2(192.168.1.101):

  • 传感器记录温度、压力和湿度。
  • Python3 脚本连接到 Raspberry Pi 3,读取传感器数据并以 JSON 格式发送到 Pi 3,每 5 秒一次。

树莓派 3 (192.168.1.100):

  • Node.js 服务器在端口 8888 上监听 Python 客户端。
  • Socket.io 在端口 3000 上监听网络客户端(端口 3000 和 80 已在我的路由器上打开)。
  • 网络服务器(端口 80),带有显示传感器数据的网站。
  • JavaScript 通过 foobar.ddns.net:3000 使用 socket.io 连接到 Node 服务器。

其他:

  • 我使用 noip.com 来拥有一个为我的动态 IP 地址提供服务的域,当我的公共(public) IP 发生变化时,我的路由器会让 noip 知道。我有一个类似于 foobar.ddns.net 的 URL。

此设置似乎有效。 Python 脚本将数据发送到 Node 服务器, Node 服务器将数据转发到任何连接的 Web 客户端,并在网站上正确显示。

我的问题是 Web 客户端在客户端和 Node 服务器之间进行 1 轮 ping/pong 后断开连接。

这是连接到服务器并接收数据时的 Chrome 控制台日志: chrome console log

网络客户端连接,接收一些数据,与服务器进行 ping/pong,接收更多数据,然后当它应该再次 ping/pong 时它会断开连接,然后过了一会儿它会尝试重新连接并继续循环。

这是 Node.js 日志:
node.js server log

第一个新连接是Python客户端(我不确定为什么IP是Pi3地址),其余的都是相同的Web客户端连接,因ping超时而断开连接,然后重新连接。根据服务器 pingInterval + pingTimeout 值,客户端似乎正在断开连接。

更改 pingTimeout 和 pingInterval 值只会延迟断开连接。

这是我的代码:

Python 客户端:

import json
import socket
import bme280_sensor
import time
import os

class Connection():

def __init__(self, host, port):
self.host = host
self.port = port

def connect(self):
print('Creating socket')
try:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error as msg:
print('Failed to create socket: %s' % msg)
raise

print('Socket created')

server_address = (self.host, self.port)
print('Connecting to %s:%s' % server_address)

try:
self.sock.connect(server_address)
except socket.error as msg:
print('Failed to connect: %s' % msg)
raise

print('Connected')

def shutdown(self):
print('Shutting down')
self.sock.shutdown(socket.SHUT_RDWR)
self.sock.close()

def measure_temp():
bme_data = bme280_sensor.read_all()
obj = {}
obj['temp'] = round(bme_data[2], 2)
obj['humidity'] = round(bme_data[0], 2)
obj['pressure'] = round(bme_data[1], 2)
return json.dumps(obj)

def sendData(sock):
print('Sending data')
while True:
try:
data = 'data,' + measure_temp()
sock.sendall(data.encode())
except socket.error as msg:
print("Cannot send to server: %s" % msg)
break

time.sleep(5)

connection = Connection('192.168.1.100', 8888)

while True:
try:
connection.connect()
sendData(connection.sock)
connection.shutdown()
break
except socket.error as msg:
print('Connection failed, retrying in 3 seconds.')
time.sleep(3)

print('Done')

Node.js 服务器:

var net = require('net');

var port = 8888;
var server = net.createServer();

// socket io listens for clients on port 3000
var io = require('socket.io')(3000,{
pingInterval: 10000,
pingTimeout: 5000,
});

// server listens for python client on port 8888
server.listen(port);

console.log('Server started');

// store the last data recorded, so when a socket.io client connects, they can get the last reading instead of waiting for the next one
global.last;

server.on('connection', function(socket){

console.log('New server connection ' + socket.address().address);

// when the server recieves data, send it to the connected socket clients
socket.on('data', function(data){

// strip the first 5 characters from the input string, parse json from the result
var actual = generateJSON(data.toString().substring(5));
// store the dta
global.last = actual;

//send the data
io.sockets.emit('data', actual);
});

});

io.on('connection', function(socket){

console.log('New io connection ' + socket.id);

// if the server has data previously recorded, send it to the new client
if(global.last){
io.emit('data', global.last);
}

socket.on('disconnect', function(reason){
console.log('io disconnect: ' + reason);
});
});

function generateJSON(data){
var dataJSON = JSON.parse(data);
var obj = new Object();

obj.temperature = dataJSON.temp;
obj.humidity = dataJSON.humidity;
obj.pressure = dataJSON.pressure;
obj.datetime = new Date().toString();

return JSON.stringify(obj);
}

网站 JavaScript:

var socket;
var connected = false;

function connect(){
console.log('connecting...')

if(socket){
socket.destroy()
delete socket;
socket = null;
}

socket = io.connect("http://foobar.ddns.net:3000", {
forceNew: true,
reconnection: true,
reconnectionDelay: 3000,
reconnectionDelayMax: 5000,
reconnectionAttempts: Infinity
});

console.log(socket);

socket.on("data", function(data){
var obj = JSON.parse(data);
console.log(data);

$('#temperature-value').text(obj.temperature);
$('#humidity-value').text(obj.humidity);
$('#pressure-value').text(obj.pressure);
lastUpdate = new Date();
});

socket.on('connect_error', function(error){
console.log('connection error: ' + error);
});

socket.on('connect_timeout', function(){
console.log('connection timeout');
});

socket.on('reconnect', function(){
console.log('reconnect');
});

socket.on('reconnect_attempt', function(){
console.log('reconnect attempt');
});

socket.on('reconnect_failed', function(){
console.log('reconnect_failed');
});

socket.on('reconnect_error', function(){
console.log('reconnect_error');
});

socket.on('reconnecting', function(){
console.log('reconnecting');
});

socket.on('ping', function(){
console.log('ping');
});

socket.on('pong', function(ms){
console.log('pong ' + ms + "ms");
});

socket.on('connect', function(){
console.log('connected to server');
connected = true;
});

socket.on('disconnect', function(reason){
console.log('disconnected from server: ' + reason);
connected = false;
});
}

$(document).ready(function(){
connect();
});

我正在使用我的index.html 中的以下内容访问socket.io.js 脚本:
<script src="http://foobar.ddns.net:3000/socket.io/socket.io.js"></script>

这是功能性的,但断开连接相当烦人,我宁愿客户端保持连接。我感觉我的 Node.js 服务器设置不正确,但我不知道问题出在哪里。如果有更好的方法从 python 脚本 > node.js 服务器 > Web 客户端提供数据,请告诉我。

谢谢

最佳答案

我已经解决了这个问题!它与node.js 或socket.io 无关。

问题出在我显示数据的网页上,我有这个方法来更新显示自上次更新以来的秒数的跨度:

function updateLastUpdateTimer(){
var seconds = (new Date() - lastUpdate) / 1000;

$('#time-since-last-update').text(formatTime(seconds) + " ago");
$('#last-updated-time').text(lastUpdate);
setInterval(updateLastUpdateTimer, 1000);
}

问题是 setInterval,而它本应是 setTimeout。我意识到我的网页正在耗尽 RAM,这导致客户端套接字挂起并且不向服务器发送任何数据,从而导致超时!

setInterval 方法每 x 毫秒运行一个函数。不要将其放在您要调用的方法中!改为调用一次。

对于阅读本文的任何人,如果对 ping 超时和传输关闭断开连接有同样的问题,请检查您的客户端!

关于javascript - Socket.io 客户端由于 ping 超时/传输关闭而断开连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51103659/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com