2016-09-14 3 views
2

현재 자바 스크립트 클라이언트에 완벽하게 연결되는 Python SocketIO 서버를 실행 중입니다. socketio android example chat app을 사용하여 Android 코드를 작성했지만 NodeJS 서버와 완벽하게 작동했지만 Python 서버를 사용하여 연결하면 연결되지 않습니다.python-socketio 백엔드에 Android 앱을 연결하는 방법은 무엇입니까?

어떻게 안드로이드에서 Ptyhon-SocketIO 서버에 연결할 수 있습니까?

안드로이드 코드 :

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 응용 프로그램에서 연결할 수 있으므로 잘 작동합니다. 파이썬 코드 :

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)

+0

누구든지 도와 주시면 감사하겠습니다. – Garth

+0

"연결되지 않습니다"라는 의미를 정확히 설명해야합니다. 서버가 완전히 안드로이드 애플 리케이션을 무시하고 있습니까? 예를 들어 서버 URL이 잘못되었을 때 어떻게 될까요? – Miguel

+0

서버에서 메시지를 보내지 만 Android 앱은 메시지를받지 않습니다. 위의 Android 코드는 NodeJS 서버를 실행 한 이후로 변경하지 않았으므로 그 연결이 작동했습니다. – Garth

답변

1

나는 SocketIO 다운로드 Python 라이브러리에서 Github

다음과 같이 예제 코드를 수정했습니다.

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"; 

그리고 안드로이드 응용 프로그램에 연결할 수 있습니다. 나는 그것을 애플과 파이썬 콘솔에서도 볼 수있다. 불필요한 구문 분석 부분을 제거하면 (응답이 다르기 때문에 응용 프로그램이 충돌 함) 파이썬에서 메시지를 볼 수도 있습니다.

먼저 SSL없이 서버 응용 프로그램을 실행 해 보았습니까?

아마도 문제 일 수 있습니다. Android에서는 IO.setDefaultSSLContext(SSLContext sslContext)을 사용하여 SSL을 설정할 수 있습니다.

+0

이 socket.io-client-java를 사용해 보았지만 연결할 수 없습니다. NodeJS 백엔드를 사용할 때 완벽하게 작동하지만 파이썬에서는 작동하지 않습니다. 어쩌면 파이썬 백엔드에서 변경해야 할 부분이 있을까요? – Garth

+0

동일한 SocketIO 버전을 사용합니까? – danesz

+0

감사합니다. 답을 수정했습니다. @Garth SSL을 사용하지 않고 사용해 볼 수 있습니까? – danesz

관련 문제