我使用这个库:
https://github.com/dpallot/simple-websocket-server
当我运行以下程序(在FreeBSD上同时使用Python 2.7和Python 3.5)时,它在305秒后超时,尽管我设置SO_KEEPALIVE
,SO_KEEPALIVE
不起作用!
#!/usr/bin/python
import socket
from SimpleWebSocketServer import SimpleWebSocketServer, WebSocket
class MyWebSocket(WebSocket):
def handleConnected(self):
print(self.address, 'connected')
self.client.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
#self.client.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 3600)
#self.client.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 3600)
self.client.settimeout(3600)
class MyWebSocketServer(SimpleWebSocketServer):
def _decorateSocket(self, sock):
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
#sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 3600)
#sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 3600)
sock.settimeout(3600)
print("socket decorated: ", sock.getsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE))
return sock
server = MyWebSocketServer('', 9000, MyWebSocket)
server.serveforever()
我使用以下HTML进行测试:
<html><head><meta charset="UTF-8"/><title>WebSocket</title>
<script type="text/javascript">
var socket;
function setupWebSocket() {
var host = "ws://XXX:9000/";
try {
socket = new WebSocket(host);
var start = (new Date()).getTime();
socket.onclose = function(msg) {
var secs = (new Date()).getTime() - start;
alert("disconnected after "+(secs/1000)+" sec");
};
}
catch(ex){
alert(ex);
}
}
</script>
</head>
<body onload="setupWebSocket()">
</body>
</html>
奇怪的是,类似的代码可以与PHP一起使用。
答案 0 :(得分:2)
TCP keep alive旨在检测对等方是否不再可访问,并确保中间有状态数据包筛选器(如在SoHo路由器中用于NAT)不会丢弃状态。它的工作原理是发送有效负载大小为0的“空”TCP数据包。
由于TCP保持活动状态不传输任何数据,如果您在应用程序级别有空闲超时(无数据传输时触发),则无效。为此,您需要发送实际数据,即某种心跳。为此,Websockets有“ping”和“pong”,请参阅documentation in python。