# Wie erstelle ich eine blockiernde Funktion?



## Empire Phoenix (18. Jan 2009)

Nunja ich brache eine blockende Funktion, diese soll dazu dienen, dass wenn ich aufn dem Client bestimmte Befehle ausführe solange gewartet wird, bis ich die Antwort bekomme, also wie die statement.executequery und so.

Die Frage ist, wie kann ich eine Function dazu bringen auf ein bestimmtes Ereignis zu warten(Tutorials snippets, Anleitungen?)?


----------



## Gelöschtes Mitglied 5909 (18. Jan 2009)

hast du dein eigenes mini protokoll geschrieben oder was?

nehm doch einfach RMI


----------



## Empire Phoenix (18. Jan 2009)

Ja, ich hatte mir ein UDP Protokoll das das der Source engine nachamt gebaut. (Das ganze ist für ei Spiel gedacht, daher UDP)

Generel kann ich auch nicht klagen, weil es ziemlich schnell ist, es fehlt mir halt nur eine Idee wie ich auf Antworten warten kann, für einige wenige Befehle brauche ich das nämlich. Falls es für die Ideenfindung hilft, 

Das Protokoll hat eine Enumeration die den Typ angibt, und ich kann beliebige runnables dynamisch an jeden Befehl tackern und auch wieder entfernen.

Daher ist halt mein Konzept sowas wie:

Funktionsstart
Eine auf die Antwort wartende Runnable erstellen, die diese Funktion unblockt.
Frage an server senden
Blocken.
-runnable wird in Folge der Antwort ausgeführt
-entblockt die Funktion und übergibt die Antwort


----------



## Gelöschtes Mitglied 5909 (18. Jan 2009)

wie wärs mit nem sleep und nem listener der bei ner eingehenden message interupt aufruft?

oder auch wait / notify / join


----------



## tuxedo (19. Jan 2009)

Wieso UDP? Bei spielen tut's auch TCP (viele großen Spiele benutzen TCP). 

Wenns nicht allzugroßes ist kannst du auch RMI oder SIMON benutzen. Die Performance ist für das allermeiste sicherlich mehr als ausreichend.

Wenn du mit TCP zu hohe Latenzen hattest, hast du vermutlich nicht den Nagle-Algo deaktiviert. RMI und SIMON haben das von Haus aus schon. 



- Alex


----------



## Empire Phoenix (19. Jan 2009)

Rmi -> nicht I-Net.
Simon -> ganz nett wohl, aber zu viel des guten, ein simpler netzcode reicht.
tcp-> nicht packetorientiert, dadurch können byteverschiebungen auftreten.


```
public static void Blockingtest() throws UnknownHostException, InterruptedException{
		final Lock lock  = new ReentrantLock(); 
		final Condition condition = lock.newCondition();
		Command bla = new Command("test",MessageType.Ping){
			@Override
			public void run(ByteBuffer byteBuffer) {
				condition.notify();
				Command.RemoveRunnable("test",MessageType.Ping);
			}
			
		};
		Command.Register(bla);
		Message test = new Message(MessageType.Ping,0);
		test.Send(InetAddress.getLocalHost(),20000);
		condition.await(2000, TimeUnit.MILLISECONDS);
	}
```

Soweit so gut, nur das ich java.lang.IllegalMonitorStateException im condition.await bekomme.
Ich weis, dass das irgetwas mit dem lock besitzer oder so zu tun hat aber wirklich verstehen tue ichs noch nicht.

Was genau mache ich falsch?


----------



## tuxedo (19. Jan 2009)

Zu RMI: Ja, ich mag's auch nicht
Zu Simon: Wieso zuviel des guten? Latenz niedrig, Overhead gering, Anwendung und Einsatz einfach.
Zu TCP: Ich meinte damit eher: Lass UDP weg. Der Aufwand dafür ist zu groß. Immerhin kann es sein dass Pakete nicht ankommen (das ist bei UDP eben der Fall). Also musst du dich auch noch darum kümmern. Dazu ist es nicht "blockierend", was man auch selbst machen muss.

Zu deinem wait/notify Problem: Probier mal die zwei Befehle in einen "synchronized" Block zu stecken. Hilfe dazu gibts in der "Java Insel".

- Alex


----------



## Empire Phoenix (19. Jan 2009)

Jup auffer Insel war ich schon habe ich aber leider nicht wirklich verstanden.

Zum Packetverlust, das ist nichtweiter wichtig,weil wenn die daten zu spät ankommen sindse sowieso nciht mehr gültig. Zum blokierend, das sind wenn überhaupt 1% aller benötigten Befehle.


----------



## tuxedo (19. Jan 2009)

Zur Insel:
Naja, man kanns auch verkomplizieren. Ich mach das meist so:


```
Object myMonitor = new Object();

synchronized (myMonitor){
myMonitor.wait();
}
```

In zum aufwecken aus einem anderen Thread heraus:


```
synchronized(myMonitor){
myMonitor.notify();
}
```

Und was ist mit der Reihenfolge? Die ist bei UDP auch nicht gewährt.

Aus den eingegangenen Paketen musst du ja eh wieder Methodenaufrufe formen. Und daher wäre RMI (im LAN) oder SIMON (im Internet) schon ganz praktisch.

Aber gut, jedem das seine.

- Alex


----------



## Empire Phoenix (19. Jan 2009)

Ah wunderbar, danke funktioniert jetzt


----------



## HoaX (20. Jan 2009)

Beim ReentrantLock muss man lock() aufrufen anstatt dem alten weg über synchronized


----------



## Gast (14. Feb 2009)

HALLO....ich würde gern auf meiner Homepage verhindern, dass User meine Daten kopieren oder den Quelltext öffnen. Bei HP im Internet sah ich mal, dass beim Klick auf die rechte Maustaste die Meldung erschien ""Sie sind nicht befugt diese Funktion auszuüben."  oder auch netter ""Bitte speichern Sie nicht unsere Daten. Senden Sie uns eine Mail."
Welchen Eintrag muss ich im Quelltext vornehmen, damit keiner meine Bilder speichert oder den Quelltext öffnet? Antworten gern an Mail  john.neidhardt@web.de

Danke Euch!


----------



## masta // thomas (14. Feb 2009)

Wie kommst du darauf, dass das etwas mit dem Thema hier zu tun hast?
Nichtsdestotrotz: du solltest deine Idee verwerfen, es gibt kein Schutzmechanismus einen Client daran zu hindern den Quelltext einzusehen - dieser muss letztlich ja an den Client übertragen werden, um in deinem Fall die Seite darzustellen. Ist er einmal übertragen, gibt es immer eine Möglichkeit ihn einzusehen. Deine Idee mit der rechten Maustaste: und was ist mit dem Menü (Firefox) Ansicht -> Seienquelltext anzeigen? Oder was ist, wenn der Client JavaScript deaktiviert hat? Schon ist dein Schutz pfutsch. Summa summarum: vergiss es. 
Was ist außerdem an einem HTML Quelltext so spannend? Oder gehts um die Bilder? Die kriegt der User auch mit einem Snapshot gespeichert.


----------

