我现在有一个设置,我正在运行一个 Flask 服务器,该服务器处理 Android 手机和树莓派 Node.js socket.io 客户端之间的 WebSocket 通信。 android socket.io 可以连接到 Flask 服务器,node.js 客户端可以连接,我可以在所有 3 个服务器之间发出消息,但是我的 android studio socket.io 客户端每 5-10 秒断开连接并重新连接。即使我离开导致其连接的活动,它也会继续执行此操作,它会连续与服务器连接和断开连接。这是android studio中的Java代码:
import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;
public class ControlPage extends AppCompatActivity {
Button greenButton;
Button redButton;
private Socket mSocket; {
try {
mSocket = IO.socket("http://192.168.1.2:5000");
} catch (URISyntaxException e) {}
}
//private EditText mInputMessageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_control_page);
mSocket.connect();
mSocket.on(Socket.EVENT_CONNECT, onConnect);
greenButton = (Button) findViewById(R.id.sendButtonGreen);
greenButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
attemptSendGreen();
}
});
redButton = (Button) findViewById(R.id.sendButtonRed);
redButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
attemptSendRed();
}
});
}
我的烧瓶代码中的服务器端:
import flask
from flask_socketio import SocketIO, emit
from flask import request
import json
app = flask.Flask(__name__)
socketio = SocketIO(app)
clients = {}
sessions = {}
@app.route('/')
def hello():
return "<h1> Hello World! </h1>"
@socketio.on('connect')
def testConnect():
print('connected')
emit('connected')
@socketio.on('disconnect')
def testDisconnect():
userSID = request.sid
print('disconnected ' + str(userSID))
UserID = sessions[str(userSID)][0]
UserType = sessions[str(userSID)][1]
clients[UserID][UserType]=''
sessions.pop(str(userSID))
@socketio.on('config')
def handle_config(data):
print('received message: ' + str(data)+ str(type(data)))
userSID = request.sid
if type(data) == str:
jsonData = eval(data)
else:
jsonData = data
print(userSID)
if jsonData['USER_KEY'] in clients:
clients[jsonData['USER_KEY']][jsonData['USER_TYPE']]=userSID
else:
clients[jsonData['USER_KEY']] = {'USER':'',
'HARDWARE':''}
clients[jsonData['USER_KEY']][jsonData['USER_TYPE']]=userSID
sessions[str(userSID)] = [jsonData['USER_KEY'], jsonData['USER_TYPE']]
@socketio.on('transfer')
def transfer(data):
jsonData = eval(data)
print(jsonData)
UserID = jsonData['USER_KEY']
UserType = jsonData['USER_TYPE']
color = jsonData['MESSAGE']
#message = data['MESSAGE']
message = {'COLOR': color,
'STATE': 1
}
jsonMessage = json.dumps(message)
if UserType == 'USER':
transferID = clients[UserID]['HARDWARE']
else:
transferID = clients[UserID]['USER']
emit('serverTransfer', jsonMessage, to=transferID)
socketio.run(app,host='192.168.1.2',port='5000') #remove this line when using gunicorn deployment
服务器端的一切都与我的node.js客户端一起正常工作,所以我不认为问题来自服务器。
这是我从服务器返回的信息,显示 Android 客户端每隔几秒断开连接并重新连接:
WebSocket transport not available. Install eventlet or gevent and gevent-websocket for improved performance.
* Serving Flask app "websocketTest" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://192.168.1.2:5000/ (Press CTRL+C to quit)
192.168.1.5 - - [18/Apr/2021 18:15:23] "GET /socket.io/?EIO=4&transport=polling HTTP/1.1" 200 -
192.168.1.5 - - [18/Apr/2021 18:15:23] "POST /socket.io/?EIO=4&transport=polling&sid=mO35rQ0Mi_5ZxYFXAAAA HTTP/1.1" 200 -
192.168.1.5 - - [18/Apr/2021 18:15:23] "GET /socket.io/?EIO=4&transport=polling&sid=mO35rQ0Mi_5ZxYFXAAAA HTTP/1.1" 200 -
192.168.1.5 - - [18/Apr/2021 18:15:23] "POST /socket.io/?EIO=4&transport=polling&sid=mO35rQ0Mi_5ZxYFXAAAA HTTP/1.1" 200 -
connected
received message: { "USER_KEY": "TEST_USER", "MESSAGE": "asdfasdfasdf", "USER_TYPE":"USER"}<class 'str'>
6pKGg55-qcP9rejgAAAB
192.168.1.5 - - [18/Apr/2021 18:15:33] "POST /socket.io/?EIO=4&transport=polling&sid=mO35rQ0Mi_5ZxYFXAAAA HTTP/1.1" 200 -
192.168.1.5 - - [18/Apr/2021 18:15:33] "GET /socket.io/?EIO=4&transport=polling&sid=mO35rQ0Mi_5ZxYFXAAAA HTTP/1.1" 200 -
disconnected6pKGg55-qcP9rejgAAAB
192.168.1.6 - - [18/Apr/2021 18:15:33] "GET /socket.io/?EIO=4&transport=polling&t=NZdidCS&b64=1 HTTP/1.1" 200 -
192.168.1.6 - - [18/Apr/2021 18:15:34] "POST /socket.io/?EIO=4&transport=polling&t=NZdidEm&b64=1&sid=6pJ6UIkNrvOanjMwAAAC HTTP/1.1" 200 -
192.168.1.6 - - [18/Apr/2021 18:15:34] "GET /socket.io/?EIO=4&transport=polling&t=NZdidEx&b64=1&sid=6pJ6UIkNrvOanjMwAAAC HTTP/1.1" 200 -
192.168.1.6 - - [18/Apr/2021 18:15:34] "POST /socket.io/?EIO=4&transport=polling&t=NZdidFW&b64=1&sid=6pJ6UIkNrvOanjMwAAAC HTTP/1.1" 200 -
192.168.1.6 - - [18/Apr/2021 18:15:34] "POST /socket.io/?EIO=4&transport=polling&t=NZdidFx&b64=1&sid=6pJ6UIkNrvOanjMwAAAC HTTP/1.1" 200 -
connected
received message: {'USER_KEY': 'TEST_USER', 'USER_TYPE': 'HARDWARE'}<class 'dict'>
1nrEBb6Xny3dpELEAAAD
192.168.1.5 - - [18/Apr/2021 18:15:35] "GET /socket.io/?EIO=4&transport=polling HTTP/1.1" 200 -
192.168.1.5 - - [18/Apr/2021 18:15:35] "POST /socket.io/?EIO=4&transport=polling&sid=Vo6Qo1Suk5U6dnG0AAAE HTTP/1.1" 200 -
192.168.1.5 - - [18/Apr/2021 18:15:35] "GET /socket.io/?EIO=4&transport=polling&sid=Vo6Qo1Suk5U6dnG0AAAE HTTP/1.1" 200 -
192.168.1.5 - - [18/Apr/2021 18:15:35] "POST /socket.io/?EIO=4&transport=polling&sid=Vo6Qo1Suk5U6dnG0AAAE HTTP/1.1" 200 -
connected
received message: { "USER_KEY": "TEST_USER", "MESSAGE": "asdfasdfasdf", "USER_TYPE":"USER"}<class 'str'>
85Gy1EZr-XWm32-6AAAF
192.168.1.5 - - [18/Apr/2021 18:15:39] "POST /socket.io/?EIO=4&transport=polling&sid=Vo6Qo1Suk5U6dnG0AAAE HTTP/1.1" 200 -
192.168.1.6 - - [18/Apr/2021 18:15:39] "GET /socket.io/?EIO=4&transport=polling&t=NZdidFj&b64=1&sid=6pJ6UIkNrvOanjMwAAAC HTTP/1.1" 200 -
{'USER_KEY': 'TEST_USER', 'MESSAGE': 'GREEN', 'USER_TYPE': 'USER'}
192.168.1.6 - - [18/Apr/2021 18:15:40] "GET /socket.io/?EIO=4&transport=polling&t=NZdieaT&b64=1&sid=6pJ6UIkNrvOanjMwAAAC HTTP/1.1" 200 -
192.168.1.5 - - [18/Apr/2021 18:15:40] "POST /socket.io/?EIO=4&transport=polling&sid=Vo6Qo1Suk5U6dnG0AAAE HTTP/1.1" 200 -
{'USER_KEY': 'TEST_USER', 'MESSAGE': 'GREEN', 'USER_TYPE': 'USER'}
192.168.1.5 - - [18/Apr/2021 18:15:41] "POST /socket.io/?EIO=4&transport=polling&sid=Vo6Qo1Suk5U6dnG0AAAE HTTP/1.1" 200 -
192.168.1.6 - - [18/Apr/2021 18:15:41] "GET /socket.io/?EIO=4&transport=polling&t=NZdiejT&b64=1&sid=6pJ6UIkNrvOanjMwAAAC HTTP/1.1" 200 -
{'USER_KEY': 'TEST_USER', 'MESSAGE': 'RED', 'USER_TYPE': 'USER'}
192.168.1.5 - - [18/Apr/2021 18:15:42] "POST /socket.io/?EIO=4&transport=polling&sid=Vo6Qo1Suk5U6dnG0AAAE HTTP/1.1" 200 -
192.168.1.6 - - [18/Apr/2021 18:15:42] "GET /socket.io/?EIO=4&transport=polling&t=NZdif2X&b64=1&sid=6pJ6UIkNrvOanjMwAAAC HTTP/1.1" 200 -
{'USER_KEY': 'TEST_USER', 'MESSAGE': 'RED', 'USER_TYPE': 'USER'}
192.168.1.5 - - [18/Apr/2021 18:15:45] "POST /socket.io/?EIO=4&transport=polling&sid=Vo6Qo1Suk5U6dnG0AAAE HTTP/1.1" 200 -
192.168.1.5 - - [18/Apr/2021 18:15:45] "GET /socket.io/?EIO=4&transport=polling&sid=Vo6Qo1Suk5U6dnG0AAAE HTTP/1.1" 200 -
disconnected85Gy1EZr-XWm32-6AAAF
192.168.1.5 - - [18/Apr/2021 18:15:47] "GET /socket.io/?EIO=4&transport=polling HTTP/1.1" 200 -
192.168.1.5 - - [18/Apr/2021 18:15:47] "POST /socket.io/?EIO=4&transport=polling&sid=Axb2tK8BaYqGqrgGAAAG HTTP/1.1" 200 -
192.168.1.5 - - [18/Apr/2021 18:15:47] "GET /socket.io/?EIO=4&transport=polling&sid=Axb2tK8BaYqGqrgGAAAG HTTP/1.1" 200 -
192.168.1.5 - - [18/Apr/2021 18:15:47] "POST /socket.io/?EIO=4&transport=polling&sid=Axb2tK8BaYqGqrgGAAAG HTTP/1.1" 200 -
connected
received message: { "USER_KEY": "TEST_USER", "MESSAGE": "asdfasdfasdf", "USER_TYPE":"USER"}<class 'str'>
RLGgcjYRr3G8437zAAAH
192.168.1.6 - - [18/Apr/2021 18:15:58] "GET /socket.io/?EIO=4&transport=polling&t=NZdifE4&b64=1&sid=6pJ6UIkNrvOanjMwAAAC HTTP/1.1" 200 -
disconnected1nrEBb6Xny3dpELEAAAD
192.168.1.5 - - [18/Apr/2021 18:16:12] "GET /socket.io/?EIO=4&transport=polling&sid=Axb2tK8BaYqGqrgGAAAG HTTP/1.1" 200 -
disconnectedRLGgcjYRr3G8437zAAAH
我用来处理 Java 中的 socket.io 的库导入为:
implementation ('io.socket:socket.io-client:2.0.0') {
exclude group: 'org.json', module: 'json'
}
任何有关导致我的 Android 客户端断开连接的原因的见解将不胜感激。
更新: 当我在端口 80 上的 Nginx、gunicorn、flask 堆栈中以部署状态运行服务器时,这个问题就消失了。仅当直接在端口 5000 上运行 Flask 时,该问题仍然存在。
有点晚了,但如果这可以帮助别人。
我认为您处于投票模式。
文档中的机制: https://socket.io/docs/v3/how-it-works/#upgrade-mechanism
你必须设置传输模式:(在 Kotlin 中)
val opts = IO.Options()
opts.transports = arrayOf(WebSocket.NAME)
socket = IO.socket("url", opts)
WebSocket.NAME 意思是“websocket”
被困在这里之后很长一段时间,我终于为最终到达这篇文章的人弄清楚了。由于 nginx.config 文件不完整,导致 socket.io 断开/重新连接。要成功代理 WebSocket 连接,您需要适当配置 Nginx。
proxy_http_version 1.1;
:该指令确保 Nginx 使用 HTTP/1.1,这是 WebSocket 连接所必需的。
proxy_set_header Upgrade $http_upgrade;
:此行告诉 Nginx 在客户端请求时启用 WebSocket 协议升级。
proxy_set_header Connection "upgrade";
:此行指定 WebSocket 连接的“Connection”标头应设置为“upgrade”。
server {
listen 80;
server_name website.com www.website.com;
location / {
include proxy_params;
proxy_http_version 1.1; # Enable HTTP/1.1
proxy_set_header Upgrade $http_upgrade; # Enable WebSocket
proxy_set_header Connection "upgrade"; # Enable WebSocket
proxy_set_header Host $host;
proxy_pass http://localhost:8000;
}
}