Jump to content

Mehrere Connects von unterschiedlichen Clients


Recommended Posts

Hallo,

 

sollte es eigentlich möglich sein, von mehr als einem Client gleichzeitig per WLAN auf einen Stack zuzugreifen oder ist das eigentlich nicht vorgesehen (weil's per USB auch keinen rechten Sinn macht)?

 

Aktuell habe ich folgendes Verhalten:

- 1. PC connected ruft enumerate auf => OK

- 2. PC connected und ruft enumerate auf

  => an beide Clients scheinen die enumerate-Events gesendet zu werden.

- der 1. PC ruft danach BrickMaster.getStackVoltage() auf und bekommt eine TimeoutException.

- der 2. arbeitet normal und kann die Stack-Voltage auslesen

- vom 1. kann ich immernoch den ServoBrick ansteuern (ohne Response)

 

Wenn's eh nicht vorgehesen ist, parallel mehrere Clients zu haben, ist alles OK.

Link to comment
Share on other sites

Antworten soweit ich mich erinnere (TF darf hier gerne widersprechen ^^):

 

sollte es eigentlich möglich sein, von mehr als einem Client gleichzeitig per WLAN auf einen Stack zuzugreifen oder ist das eigentlich nicht vorgesehen (weil's per USB auch keinen rechten Sinn macht)?

Sollte bei beiden gehen. Insbesondere bei USB wurde zu 1.0 Zeiten viel Schweiß investiert, dass das klappt.

 

  => an beide Clients scheinen die enumerate-Events gesendet zu werden.

 

Das ist soweit ich weiß, erwartetes Verhalten.

 

- der 1. PC ruft danach BrickMaster.getStackVoltage() auf und bekommt eine TimeoutException.

- der 2. arbeitet normal und kann die Stack-Voltage auslesen

- vom 1. kann ich immernoch den ServoBrick ansteuern (ohne Response)

 

Das klingt nach Fehlverhalten.

 

Kann allerdings sein, dass TF irgendwann zwischendurch beschlossen hat, dass mehrere Clients nciht mehr supported werden sollen. Fände ich aber schade, da es viele Anwendungsfälle gibt (gerade im Bereich Ansteuerung durch Android/iOS) wo das funktionieren sollte.

Link to comment
Share on other sites

Du meinst von mehreren PCs per WLAN drauf zugreifen? Das geht, klar. Die WIFI Extension sollte sich da wie brickd verhalten. Brickd weiß zum Beispiel auch nicht für wen ein Callback bestimmt ist und schickt ihn überall hin. Bei WIFI können bis zu 15 IP Verbindungen gleichzeitig benutzt werden (das ist auch durchgetestet).

 

Deine Problembeschreibung klingt so, als würdest du über einen PC per USB verbinden und über den anderen per WIFI: Das geht leider nicht und ist auch technisch nicht möglich.

 

Wenn du zwei Schnittstellen gleichzeitig benutzt gehen Nachrichten immer an die Schnittstelle, die zuletzt etwas angefragt hat (das gilt sowohl für Getter als auch für Callbacks).

 

Also wenn du z.B. per WIFI einen Stackteilnehmer abfragst und bevor der die Antwort zurück schickt fragst du etwas per USB ab, geht die Antwort der ersten Anfrage per USB zurück.

Link to comment
Share on other sites

Ich verbinde hier zwei Clients (von unterschiedlichen Quell-IPs) ausschließlich über WLAN.

Der Stack hat keine USB-Connection und wird über Step-Down mit Strom versorgt.

 

Beide Clients "pollen" alle 2 Sekunden Spannung/Strom vom Master und nachdem sich der 2. Client connected hat bekommt der Erste beim abfragen der Daten eine TimeoutException. Ich bediene nicht beide Schnittstellen (USB + WLAN) gleichzeitig.

Link to comment
Share on other sites

Das ist komisch. Wenn ich hier auf meinem PC und Laptop einen Brickv starte und die beide mit einem WIFI Extension verbinde und den Master Tab aufmache, klappt das einwandfrei.

 

Der Brick Viewer macht in dem Fall nichts anderes als alle 100ms GetStackVoltage/GetStackCurrent aufzurufen.

 

Machst du irgendwas besonderes? Womit ich das vielleicht reproduzieren kann?

Link to comment
Share on other sites

Ich dachte eigentlich, dass ich nichts besonderes mache.

Hier ein Beispiel, ist mir nicht damit aufgefallen, zeigt aber dennoch den Effekt.

 

- in den Sourcen 1x die Main-Klasse mit der Option "ns" starten

  => liest nur noch Spannung aus, alle 2 Sekunden, 15x

- das gleiche vom selben oder einem anderen Rechner nochmal starten

 

Einer der Clients bekommt dann immer eine Timeoutexception.

 

(Hinweis: fehlt die Option, wird noch ein Server angesteuert, das sollte tunlichst nur von einem Rechner passieren.)

BrickTest.zip

Link to comment
Share on other sites

Ich kann das Problem mit deinem Code nachstellen, allerdings nicht mit einem Minimalbeispiel:

 

import com.tinkerforge.BrickMaster;
import com.tinkerforge.IPConnection;

public class ExampleStackStatus {
private static final String host = "192.168.178.108";
private static final int port = 4223;
private static final String UID = "68daHU"; // Change to your UID

// Note: To make the example code cleaner we do not handle exceptions. Exceptions you
//       might normally want to catch are described in the documentation
public static void main(String args[]) throws Exception {
	IPConnection ipcon = new IPConnection(); // Create IP connection
	BrickMaster master = new BrickMaster(UID, ipcon); // Create device object

	ipcon.connect(host, port); // Connect to brickd
	// Don't use device before ipcon is connected

	for(int i = 0; i < 10; i++) {
		// Get voltage and current from stack (in mV/mA)
		int voltage = master.getStackVoltage();
		int current = master.getStackCurrent();

		System.out.println("Stack Voltage: " + voltage/1000.0 + " V");
		System.out.println("Stack Current: " + current/1000.0 + " A");
		Thread.sleep(1950);
	}

	System.console().readLine("Press key to exit\n");
	ipcon.disconnect();
}
}

 

Sag Bescheid wenn du herausfindest woran es genau liegt ;D.

 

wenn der 2. Client den Enumerate startet wird das ja auch an den 1. Client gemeldet. Im 1. Client initialisiere ich meine Strukturen aber nicht neu und nutze weiter die vorhandenen Devices mit den bekannten UIDs. Kann das ein Problem sein?

Das ist OK, du musst nur neu initialisieren wenn der Stack aus war und seine Konfiguration vergessen hat.

Link to comment
Share on other sites

Ich glaub ich hab' das Problem schon:

meine Implementierung des enumerate() war nicht darauf vorbereitet, völlig "unkontrolliert" ein 2. mal aufgerufen zu werden, weil sich ein anderer Client connected und den enumerate() auslöst. Dadurch wird ein Device mit einer UID 2x in der IPConnection registriert.

 

Der ipcon.devices.put(..) wirft aber die zuerst registrierte Instanz aus der Map der IPConnection. Aber genau diese Instanz wird von meiner Anwendung noch benutzt => das kann nicht klappen.

 

Danke für den Denkanstoss.

Link to comment
Share on other sites

Theoretisch könnten die Bindings überprüfen, ob ein Device das die IPConnection gerade benutzt auch noch in der IPConnection bekannt ist. Falls nicht könnten sie statt einer TimeoutException nach 2 Sekunden, besser sofort eine IllegalStateException mit hilfreichem Text werfen.

 

(Bei Java sollte man aber darauf achten, dass es sich dabei auch um eine (Subklasse von) RuntimeException handelt, da diese Exception nicht checked sein sollte.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...