如何将 Android 应用程序连接到 python-socketio 后端?
Posted
技术标签:
【中文标题】如何将 Android 应用程序连接到 python-socketio 后端?【英文标题】:How to connect Android app to python-socketio backend? 【发布时间】:2017-01-22 05:29:55 【问题描述】:我目前正在运行一个可以完美连接到我的 javascript 客户端的 Python SocketIO 服务器。我正在使用socketio android example chat app 编写 Android 代码,它与 NodeJS 服务器完美配合,但是当我改用 Python 服务器时,它无法连接。
如何从 Android 连接到 Ptyhon-SocketIO 服务器?
Android 代码:
public class HomeActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener
private final String TAG = "MainActivity";
Button btnCore0, btnCore1, btnCPUUsage;
private ProgressBar progressBar;
private Socket mSocket;
try
mSocket = IO.socket(Constants.SERVER_URL);
catch (URISyntaxException e)
Log.e(TAG, e.getMessage());
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
btnCore0 = (Button) findViewById(R.id.btnCore0);
btnCore1 = (Button) findViewById(R.id.btnCore1);
btnCPUUsage = (Button) findViewById(R.id.btnCPUUsage);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
// Make buttons invisible
btnCore0.setVisibility(View.INVISIBLE);
btnCore1.setVisibility(View.INVISIBLE);
btnCPUUsage.setVisibility(View.INVISIBLE);
// Make progress bar visible
progressBar.setVisibility(View.VISIBLE);
mSocket.on("status-update", onNewMessage);
mSocket.on(Socket.EVENT_DISCONNECT, onSocketDisconnected);
mSocket.connect();
private Emitter.Listener onNewMessage = new Emitter.Listener()
@Override
public void call(final Object... args)
HomeActivity.this.runOnUiThread(new Runnable()
@Override
public void run()
Log.d(TAG, "New message 090909***");
JSONObject data = (JSONObject) args[0];
int core0 = 0;
int core1 = 0;
int cpu_usage_in = 0;
try
core0 = data.getInt("core0_in");
core1 = data.getInt("core1_in");
cpu_usage_in = data.getInt("cpu_usage_in");
catch (JSONException e)
Log.e(TAG, e.getMessage());
btnCore0.setText(getResources().getString(R.string.core0, String.valueOf(core0)));
btnCore1.setText(getResources().getString(R.string.core1, String.valueOf(core1)));
btnCPUUsage.setText(getResources().getString(R.string.cpu_usge, String.valueOf(cpu_usage_in)));
updateButtonBackgroundColor(btnCore0, core0);
updateButtonBackgroundColor(btnCore1, core1);
updateButtonBackgroundColor(btnCPUUsage, cpu_usage_in);
onServerDataReceived();
);
;
接下来是每秒发出一次的 Pyhton 服务器。我知道这可以正常工作,因为我可以从 JavaScript 应用程序连接到它。 Python 代码:
from flask import Flask, render_template
from flask_socketio import SocketIO
from gcm import GCM
eventlet.monkey_patch()
app = Flask(__name__)
socket = SocketIO(app, logger=True, engineio_logger=True)
class Server(threading.Thread):
def __init__(self, thread_id):
threading.Thread.__init__(self)
self.threadID = thread_id
def run(self):
print("Starting " + self.name)
serve()
print("Exiting " + self.name)
def serve():
if __name__ == '__main__':
eventlet.wsgi.server(eventlet.wrap_ssl(eventlet.listen(('', 8000)), certfile='/home/garthtee/cert.pem', keyfile='/home/garthtee/privkey.pem'), app)
server_thread = Server("Server-thread")
server_thread.start()
threads.append(server_thread)
print("Started @ " + str(get_time()))
while True:
sensors.init()
try:
for chip in sensors.iter_detected_chips():
# print('%s at %s' % (chip, chip.adapter_name))
for feature in chip:
if feature.label == 'Core 0':
core0 = feature.get_value()
elif feature.label == 'Core 1':
core1 = feature.get_value()
for x in range(1):
cpu_usage = str(psutil.cpu_percent(interval=1))
finally:
socket.emit('status-update', 'core0_in': core0, 'core1_in': core1, 'cpu_usage_in': cpu_usage, 'users': users)
alert_checker(avg_temp, users)
sensors.cleanup()
time.sleep(1)
出现以下错误:
SSLError: [SSL: SSL_HANDSHAKE_FAILURE] ssl 握手失败 (_ssl.c:1754)
【问题讨论】:
您需要准确解释“无法连接”的含义。服务器是否完全忽略了 Android 应用程序,例如如果服务器 url 错误会发生什么? 服务器发出消息 ok,但 Android 应用不会收到。我有上面的 Android 代码,因为我运行的是 NodeJS 服务器,所以我没有更改它,连接可以正常工作。 我也遇到了 SSL 握手错误,也许这是我的问题? 【参考方案1】:我从Github下载了SocketIO python库
我将示例代码修改如下:
import socketio
import eventlet
import eventlet.wsgi
from flask import Flask, render_template
sio = socketio.Server()
app = Flask(__name__)
@app.route('/')
def index():
"""Serve the client-side application."""
return render_template('index.html')
@sio.on('connect', namespace='/')
def connect(sid, environ):
print("connect ", sid)
@sio.on('add user', namespace='/')
def login(sid, environ):
print("login ", sid)
sio.emit('login', room=sid)
@sio.on('new message', namespace='/')
def message(sid, data):
print("message ", data)
sio.emit('reply', room=sid)
@sio.on('disconnect', namespace='/')
def disconnect(sid):
print('disconnect ', sid)
if __name__ == '__main__':
# wrap Flask application with engineio's middleware
app = socketio.Middleware(sio, app)
# deploy as an eventlet WSGI server
eventlet.wsgi.server(eventlet.listen(('', 8000)), app)
然后我克隆了 Android example chat 项目,以及我在 Constants.java 中更改的唯一内容:
public static final String CHAT_SERVER_URL = "http://MY_LOCAL_IP:8000";
Android 应用可以连接。 我在应用程序中看到它,也在 python 控制台中看到它。 如果你去掉了一些不必要的解析部分(应用程序崩溃了,因为响应不同),你也可以在 python 中看到你的消息。
您是否尝试过先在没有 SSL 的情况下运行您的服务器应用程序?
也许这就是问题所在。
在 Android 上,您可以使用 IO.setDefaultSSLContext(SSLContext sslContext)
设置 SSL。
【讨论】:
我已经尝试使用这个 socket.io-client-java 但我无法连接到它。当我使用 NodeJS 后端时,它可以完美运行,但不适用于 Python。也许 Python 后端需要改变一些东西? 你们使用相同的 SocketIO 版本吗? 谢谢,我修改了答案。 @Garth 你能在没有 SSL 的情况下试试吗? 检查这个:chariotsolutions.com/blog/post/…,挑战 #2:信任自签名服务器证书 我也发现了这个问题,以防有人来这里:***.com/questions/16183753/…以上是关于如何将 Android 应用程序连接到 python-socketio 后端?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 MS ACCESS 连接到 Android 应用程序
如何将 Android 应用程序连接到 MySQL 数据库? [复制]
如何将 android 应用程序连接到 MYSQL 服务器并从中检索数据?