# Socketverbindung Proxy



## RelaX (30. Mai 2014)

Hallo alle zusammen,

ich hab hier in Android ein kleines Problem welches unter Java so nie Probleme gemacht hat.

Ich hab eine Client-Server-Verbindung und benutze für die eingehenden Daten/Objecte einen selbstgeschriebenen Proxy welcher die einzelnen Objecte auseinander hält und gegebenenfalls Aktionen ausführt.

Hier ist meine MainActivity:

```
public class MainActivity extends ActionBarActivity {
	
	public static boolean serviceRunning = false;
	

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		if (savedInstanceState == null) {
			getSupportFragmentManager().beginTransaction()
					.add(R.id.container, new PlaceholderFragment()).commit();
		}
		if(!serviceRunning) {
			startService(new Intent(this, ClientService.class));
			serviceRunning = true;
		}
		
	}

        public void login(View view) {
		EditText userNameText = (EditText) findViewById(R.id.editText1);
		String username = userNameText.getText().toString();
		
		EditText passwordText = (EditText) findViewById(R.id.editText2);
		String password = passwordText.getText().toString();
		
		Bundle loginDaten = new Bundle();
		loginDaten.putString("username", username);
		loginDaten.putString("password", password);
		
		Intent in = new Intent("de.app.LOGIN");
		in.putExtras(loginDaten);
		LocalBroadcastManager.getInstance(this).sendBroadcast(in);
	}
}
```

Und hier ist meine Client Klasse:

```
public class Client extends AsyncTask<String, Void, String> {
	
	public static ClientCrypt crypt;
	
	private Socket client;
    public static ObjectOutputStream writer;
    
    public static User user;
    
    public static int startCount = 0;
    
    public InputStream keyInput;
    
    public static Context context;
	
	public Client(InputStream keyInput) {
                //nicht relevant
		this.keyInput = keyInput;
	}
	
	public void login(Context context, String username, String password) {
                //nicht relevant hier geschieht eine Verschlüsselung...
		Client.context = context;
		String encryptPassword = password;
			
		LoginEvent loginengine = new LoginEvent(username, encryptPassword, publicKey, aes);
                //loginEvent wird verschickt  <-----
		sendToServer(loginengine);
	}
	
	
	public void createCrypt() {
		try {
			crypt = new ClientCrypt(keyInput);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public boolean connectToServer() {
        try {
        	//TODO
            client = new Socket("www.addresse.de", 3333);
            
            writer = new ObjectOutputStream(client.getOutputStream());
            Thread t = new Thread(new MessagesFromServerListener(new ObjectInputStream(client.getInputStream())));
            t.start();
            //testlogin();
            return true;
            
        } catch(Exception e) {
            e.printStackTrace();
            
            		  
            return false;
        }
    }
	
	public void run() {
    }
	
	public void sendToServer(Object o) {
		try {
			Client.writer.writeObject(o);
			Client.writer.flush();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}

	@Override
	protected String doInBackground(String... params) {
		connectToServer();
        createCrypt();
        Log.d("MyApp","SERVER VERBUNDEN!!!<------------------");
        return "Executed";
	}
	
	public static void loginChecked() {

	}
	
}
```

Hier ist der zuständige Service


```
public class ClientService extends Service {
	
	private ClientServiceBinder cBinder = new ClientServiceBinder();
	public Client client;
	
	
	public class ClientServiceBinder extends Binder {
		//Schnittstelle vom Binder
	}

	@Override
	public IBinder onBind(Intent intent) {
		return cBinder;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		InputStream ins = getResources().openRawResource(
	            getResources().getIdentifier("publicc",
	            "raw", getPackageName()));

		IntentFilter inFi = new IntentFilter();
		inFi.addAction("de.app.LOGIN");
		LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getApplicationContext());
		lbm.registerReceiver(new BroadcastReceiver()
		{
			
			@Override
			public void onReceive(final Context context, final Intent intent) {
				new Handler().post(new Runnable() {
					public void run() {
						if(intent.getAction().equals("de.app.LOGIN")) {
							Bundle loginData = intent.getExtras();
							String username = loginData.getString("username");
							String password = loginData.getString("password");
							client.login(context, username, password);
							
							/*
							Toast.makeText(getApplicationContext(),
										   "Kam an!!!", 
										   Toast.LENGTH_LONG)
							.show();*/
						}
				    }
				});				
			}
		},inFi);
		client = new Client(ins);
		client.execute("");
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
	}

}
```


Hier ist mein Listener der auf den Server wartet und falls etwas ankommt an die Proxyklase weitergibt:

```
public class MessagesFromServerListener implements Runnable {
	
	private ObjectInputStream reader;
	private Proxy proxy;
	
	Object o;
	
	public MessagesFromServerListener(ObjectInputStream reader) {
		this.reader = reader;
		proxy = new Proxy();
	}

	public void run() {
		try {
            while((o = reader.readObject()) != null) {
            	proxy.executeTransfer(o);
            }
        } catch (IOException e) {
                e.printStackTrace();
        } catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
    }
	
}
```

Und zu guter letzt meine Proxyklasse die für die Verwaltung der Object zuständig ist
Von hier aus müsste ich wieder zurück in den GUI-Thread um dort weiter zu agieren:


```
public class Proxy {
	
	private final Proxy1 proxy1;
	private final Proxy2  proxy2;
	private final Proxy3 proxy3;

	public Proxy() {
		proxy1 = new Proxy1();
		proxy2 = new Proxy2();
		proxy3 = new Proxy3();
	}

	public synchronized void executeTransfer(final Object o) {
		if (o instanceof Proxy1Event) {
			proxy1 .executeTransfer(o);
		} else if (o instanceof Proxy2Event) {
			/*
			 * Wurde ein LoginEvent versendet trifft dieses Event vom Server ein.
			 * Es folgt eine Aktualisierung der GUI nach dem Erfolgreichen Login.
			 */
			if (o instanceof LoginChecked) {
				if (((LoginChecked) o).getStatus()) {

                   //Hier knallt es da ich nicht weiß wie ich auf die GUI komme.
					((Activity) Client.context).runOnUiThread(new Runnable() {
							public void run() {
								Toast.makeText(Client.context,
											"Eingeloggt!!!", 
											Toast.LENGTH_LONG)
										.show();
					    }
					});		
				} else {
					((Activity) Client.context).runOnUiThread(new Runnable() {
						public void run() {
							Toast.makeText(Client.context,
										"Einlogdaten falsch!!!", 
										Toast.LENGTH_LONG)
									.show();
						}
					});		
				}
				
				
			}
		}
	}

}
```
Ich weiß das ich mit Asynctask bestimmte aufgaben erledigen könnte allerdings brauch ich eine Socketverbindung die einfach auf bleibt.

Ich hoffe das mir jemand helfen kann da das alles noch neu für mich ist. Ich bedanke mich schon im Vorraus für die viele Arbeit. Ich suche in der Zwischenzeit weiter nach einer Lösung.


----------

