Java Variable aus methode verwenden (API)

JavaBeginner

Ensign
Registriert
Juli 2015
Beiträge
142
Hey, nachdem ich mein Sockt-Ziel erreicht habe, habe ich nun bei einem anderen kleinen Projekt ein Problem.
Wie ist es möglich die Variable aus einer Methode global zu verwenden (ohne sie ein weiteres mal zu verändern)?
Ich verwende die Ts3-API von TheHolyWaffle.
Die Methode
Code:
public static TS3Api connecting(){
		TS3Config config = null;
		TS3Query query = null;
		TS3Api api = null;
		if(query.getSocket()==null){
		config = new TS3Config();
		query=new TS3Query(config);
		TS3Api TS3Api = query.getApi();
		config.setHost("ServerIP");
    	config.setQueryPort(10011);
		query.connect();

		api.login("ServerAdmin", "Passwort");
		api.selectVirtualServerByPort(9987);
		api.setNickname("ServerBot");
		return api;
		}return api;
    }
und die Weitergabe in der Klasse:
Code:
        final TS3Api api = connecting();
        api.sendServerMessage("Bot is online!");
	connect.connection(api);
der Aufrud aus einer weiteren Klasse (Eventbedingt):
Code:
TS3Api api = tsapitesting.connecting();
		  api.sendServerMessage(e.getMessage());

Es funktioniert (bedingt) mein Problem ist, dass die api immer neu definiert wird. Sie sollte nach dem 1. mal Verbinden konstant die selbe bleiben und bei aufrufung der Methode, falls eine aktive Verbindung besteht nur die api variable zurückgegeben werden. Bisher ist das jedoch nicht der Fall, es wird immer eine neue Verbindung aufgebaut.
 
Zuletzt bearbeitet:
Hallo,

in Zeile 3 des ersten Listings setzt du die Variable "query" auf "null". In Zeile 5 rufst du auf die Variable (welche nun auf "null" gesetzt ist) die Methode "getSocket()" auf. An dieser Stelle müsstest du eine NullReferenceException bekommen. Wenn dies nicht der Fall ist, hast du an einer anderen Stelle eine Variable mit gleichem Namen definiert (z.B. irgendwo global in der Klasse). Da solltest du auf jeden Fall noch einmal nachschauen.

Zum grundlegen Problem: Was du erreichen möchtest, ähnelt relativ stark dem Singleton-Muster. Dies wird gewöhnlich implementiert, indem die Instanz der Klasse, welche du erzeugen möchtest (in deinem Fall eine "TS3Api"-Instanz) statisch als Klassenvariable definiert wird, aber noch nicht mit "new ...." instanziiert.
Damit enthält sie vorerst den Wert "null". Wenn die connect-Methode dann aufgerufen wird, überprüfst direkt am Anfang deine Klassenvariable auf "null". Trifft dies zu, konfigurierst und instanziierst du diese wie du es jetzt auch tust. Andernfalls gibst du einfach nur die vorhandene Instanz zurück.

Code:
private static TS3Api api = null;
public static TS3Api connecting()
{
     if(api == null)
     {
		TS3Config config = null;
		TS3Query query = null; 
		config = new TS3Config();
		query=new TS3Query(config);
		api = query.getApi();
		config.setHost("ServerIP");
    	        config.setQueryPort(10011);
		query.connect();
 
		api.login("ServerAdmin", "Passwort");
		api.selectVirtualServerByPort(9987);
		api.setNickname("ServerBot");
	}

        return api;
}

Gruß
 
Zuletzt bearbeitet:
Wow, danke. Das ist perfekt :D
Hätte da noch eine Frage, ich habe nun das Problem das alles zeitversetzt ist, da es erst an den Ts3 gesendet werden muss. Wie kann ich diese Zeit verkürzen/nahezu auf 0 setzen?
Code:
	@EventHandler
	public void onChat(AsyncPlayerChatEvent e) {       
		  message(e.getMessage());
     

	}	public void message(String string){
		TS3Api api = tsapitesting.connecting();
		  api.sendServerMessage(string);
	}
Habe überlegt ob noch eine weitere Methode die das an message weitergibt vielleicht etwas bringt, bezweifle es jedoch da es den Weg ja noch länger macht. Bei mehreren Spielern die eine Nachricht senden bricht das reinste Chaos aus. Wie könnte man das lösen?
 
Ich kenne mich mit der Api, die du benutzt, nicht aus. Generell ist aber zu sagen, dass bei Netzwerkkommunikation immer eine gewisse Latenz dabei ist. Aus deinem Listing kann ich keinen Grund erkennen, der für eine größere Verzögerung sorgen könnte. Wenn du die Verzögerung verringern möchtest, ist der beste Ansatz dich weiter in die Api einzulesen mit dem Stichwort "Latenz" im Hinterkopf. Mit einer Verzögerung von 20-100 Millisekunden wirst du aber immer rechnen müssen.
 
Das ist Minecraft/Ts3.
Das Event wird über die SpigotAPI(Minecraft) regestriert und über die Ts3API weiterverwendet.
Der Minecraft und Ts3-Server laufen beide auf dem selben root. Eine kleine Verzögerung ist an sich ja kein Problem, diese wird jedoch mit der Azahl der Spieler die etwas schreiben erheblich größer. Ich habe mit 6 Personen einen regen Chat-Verkehr simuliert, die letzte Nachricht kam etwa 2-3 Sekunden verzögert an(im Spiel war diese weitaus später als im Teamspeak zu sehen). Wäre es sinnvoller die Nachrichten zu sammeln und in einem 10 Sekunden interval auf dem Ts3 auszugeben?
 
Das Sammeln der Nachrichten vor dem Ausliefern würde vermutlich schon helfen. Mehrere Sekunden Verzögerung klingen aber eher nach einem anderen Grund, so groß sind die Datenmengen von eine paar Strings nicht. Ich würde an deiner Stelle erst einmal versuchen, herauszufinden, welcher Schritt in der Verarbeitungskette einer Nachricht wie lange dauert. Dazu würde ich mir die Ausgabe des Befehls "System.currentTimeMilliseconds()" (oder so ähnlich) an den relevanten Stelle im Quelltext ansehen und ermitteln, wo genau die Verzögerung auftritt. Danach kannst du dann versuchen, den entsprechenden Schritt zu optimieren.
 
Alles klar, ich danke dir vielmals für deine Hilfe. Ohne dich wäre ich sicherlich aufgeschmissen gewesen :)
 
Zurück
Oben