4

I am currently running a Python SocketIO server that connects perfectly to my JavaScript Client. I am using the socketio android example chat app to write the Android code, it worked perfectly with a NodeJS server but when I change over to using the Python server it won't connect.

How can I connect to the Ptyhon-SocketIO server from Android?

Android code:

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();
            }
        });
    }
};

Next is the Pyhton server that emits every second. This, I know works fine as I can connect to it from a JavaScript app. Python code:

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)

The following error shows up:

SSLError: [SSL: SSL_HANDSHAKE_FAILURE] ssl handshake failure (_ssl.c:1754)

3
  • You need to explain in exact terms what you mean by "it won't connect". Is the server completely ignoring the Android app, like for example what would happen if the server url is wrong? Commented Sep 14, 2016 at 20:27
  • The server emits the message ok, but the Android app won't receive it. I have the Android code above I have not changed it since I was running a NodeJS server, the connection worked with that. Commented Sep 14, 2016 at 20:44
  • 1
    I was also getting a SSL handshake error maybe this is my problem? Commented Sep 14, 2016 at 20:47

1 Answer 1

3

I downloaded the SocketIO python library from Github

I modified the example code like this:

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)

Then I cloned the Android example chat project, and the only thing what I changed in the Constants.java:

public static final String CHAT_SERVER_URL = "http://MY_LOCAL_IP:8000";

And the Android app can connect. I see it in the app, and also in the python console. If you remove some unnecessary parsing part (the app is crashing, because the response is different), you can also see your messages in python.

Have you tried to run your server app without SSL first?

Maybe that is the problem. On Android you can use IO.setDefaultSSLContext(SSLContext sslContext) to setup SSL.

Sign up to request clarification or add additional context in comments.

7 Comments

I have tried using this socket.io-client-java but I can't connect to it. When I use the NodeJS backend it works perfectly, but won't work with Python. Maybe there's something that needs to changed for a Python backend?
Do you use the same SocketIO versions?
Thanks, I modified the answer. @Garth Could you try it without SSL?
Check this: chariotsolutions.com/blog/post/… , Challenge #2: Trusting a Self-Signed Server Certificate
I also found this question in case anyone gets here: stackoverflow.com/questions/16183753/…
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.