# Timer richtig integrieren



## MettMax (9. April 2007)

Hallo Leute,
ich brauche einen Timer, der alle paar Sekunden die Klasse TP(); ausführt.
Generell ist mir der Aufbau von Timern bekannt und ich habe auch schon öfters welche benutzt. Aber in meinen jetzigen Code bekomm ich ihn nicht implementiert.
Ich war schonmal soweit, dass ich fehlerfrei kompilieren konnte aber der Timer wurde nicht gestartet.
Das Problem liegt an der Gestaltung meiner Klassen...
Ich poste einfach mal den Code:

```
package vc;
import org.red5.server.adapter.ApplicationAdapter;
import java.util.Timer;
import java.util.TimerTask;


public class application extends ApplicationAdapter implements Runnable
{
   
   int maxUsers = 12;

   String[][] UserList = new String[100][13];
   float[][]  LastActivity = new float[100][13]; 
   int[][] UserSpeaking = new int[100][13]; //100 Räume á 12 User
  
   public String ToClient(int ID, int room)
   {
     
     return GetUserlist(room) + ";" + GetUserSpeaking(room) + ";" + TP(ID,room);
   }
   
	 public String RegisterID(int ID, String Username, int room)
	 {
	 String UsernameReserved = "no";
	 for (int i=1;i<=maxUsers;i++){
	  if(UserList[room][i]==Username){
	   UsernameReserved = "yes";
	   break;
	   }
	  }
	  if(UserList[room][ID]== null && UsernameReserved == "no"){
	    UserList[room][ID] = Username;
	    return "You are known as:" + UserList[room][ID] + "." + UsernameReserved;
      }
	   else
	   return "Failed, to register ID. Please reload the application. Username already in use?";
	 }
	  public String UnRegisterID(int ID, int room)
	 {
	  UserList[room][ID] = null;
	  UserSpeaking[room][ID] =0;
    return "Logged out.";
	 }
  
   public int ResolveID(int room)
	 {
    int ID=-1;
    for(int i=1;i<=maxUsers;i++)
     if(UserList[room][i]==null){
       ID = i;
       break;
      }
    return ID;
   }
   public void LightOn(int user, int room)
   {
    UserSpeaking[room][user] = 1;
   } 
   public void LightOff(int user, int room)
   {
    UserSpeaking[room][user] = 0;
   }
   
   public String GetUserSpeaking(int room)   //Gibt zurück welche Benutzer gerade sprechen
   {
    String InfoString ="";
     for (int i=1;i<=maxUsers;i++){  //!!
      InfoString = InfoString + UserSpeaking[room][i] + "#";
      }
   return InfoString;
   }
   
   public String UserInfo(int ID, int room)   //Sucht Benutzernamen nach ID
   {
    return UserList[room][ID];
   }
   public String GetUserlist(int room)   //Gibt Userliste zurück
   {
    String InfoString ="";
     for (int i=1;i<=maxUsers;i++){  
       InfoString = InfoString + UserList[room][i] + "#";
       }
     return InfoString;
   }
   public long TP(int ID, int room)
   {
     
    return System.currentTimeMillis()/1000;
  
   }

}
```

Ich hab meine Versuche mal entfernt, da sie doch eher unheldenhaft  waren...
Könnt ihr mir irgendwelche Tipps geben wie ich einen Timer integriert bekomme.
Ich möchte gerne die java.util.Timer; java.util.Timertask verwenden, also nicht javax.swing.timer..

Danke und schönen Abend noch
Max


----------



## zeja (10. April 2007)

Hmm mit so unformatiertem Code könnte ich auch nicht programmieren.

Wie auch immer noch ein paar Kleinigkeiten:
Klassennamen schreibt man gross, Methodennamen dagegen beginnen immer klein, genauso wie Variablennamen.


```
int[][] UserSpeaking = new int[100][13]; // 100 Räume á 12 User
```

So passen aber 13 User rein.

Und TP ist bei dir eine Methode und keine Klasse.

Ich weiss daher auch gerade nicht was dieser Timer genau tun soll.


----------



## MettMax (10. April 2007)

Hey,




> ```
> 1.
> int[][] UserSpeaking = new int[100][13]; // 100 Räume á 12 User
> 2.
> ...


Eigentlich sogar 14 ... 

Was die Formatierung angeht gebe ich dir recht, das liegt daran dass ich keinen vernünftigen Editor benutze, weil ich direkt auf meinem Server arbeite und deswegen einen Editor brauche mit dem ich mich Verbinden kann und direkt dort speichern kann.
TP ist keine Klasse, auch da hast du recht...

Also, ich muss irgendwie überprüfen ob ein User die Verbindung getrennt hat, ohne auf Logout geklickt zu haben. Weil sein PC z.B abgestürzt ist.
Ich habe das so geplant :
Jede Sek. ruft der Client die Methode TP() auf und bekommt einen Timestamp vom Server. Der Client sendet darauf diesen Timestamp an den Server zurück. Der Server zieht beide Timestamps von einander ab, und wenn die Differenz über 10sek ist, wird die Verbindung getrennt.

Ich muss also einen Timer haben, der jede Sekunde timestamp1-timestamp2 ausführt und die Differenz in einer einfachen if schleife mit einem Richtwert vergleicht.

Also wenn man als Beispiel das Listning 9.30, 9.31 auf http://www.galileodesign.de/openbook/javainsel5/javainsel09_009.htm nimmt, dann sollte es ungefähr so aussehen.

```
import java.util.Timer;
import java.util.TimerTask;
class Task   extends TimerTask
  {
  @Override   public void run()
    {
    for(int i = 1; i<=maxUsers; i++){
    if(Servertimestamp - timestamp[room][i] > 10)
     UnregisterID(i,room);
    }
  }
}
```



```
public class TimerTaskDemo
{
  public static void main( String[] args )
  {
    Timer timer = new Timer();
      timer.schedule  ( new Task(), 1000, 1000 );
  }
}
```

Mir ist klar, dass es mit :

```
for(int i = 1; i<=maxUsers; i++){
    if(Servertimestamp - timestamp[room][i] > 10)
     UnregisterID(i,room);
```

nicht getan ist, da dies nur für einen Raum gelten würde, aber was ich vor habe sollte dadurch verdeutlicht werden.
Das Problem ist nur, dass ich den Timer zwar schon fehlerfrei integriert hatte, aber ich ihn nicht starten konnte. Weil ich keine Ahnung habe, wie ich den Aufbau dieses Timers an meine Strukturen adaptieren kann.

Lieben Gruß 
Max


----------



## zeja (11. April 2007)

13.... von 0 - 12

Nunja wenn der Client aber nicht mehr antwortet, klappt das mit deinem Timestamps hin und herschicken auch nicht.

Am besten wäre es wenn der Client jeweils einen Timer hätte und alle 10 Sekunden einen Timestamp an den Server schickt und der Server in einem Thread immer mal wieder alle Clients durchgeht und schaut ob auch alle noch Timestamps schicken und diese ansonsten rausschmeisst.


----------



## MettMax (11. April 2007)

Hey!

Ja, aber mein Array war ja sogar bis 13 definiert.

```
int[][] UserSpeaking = new int[100][13];
```
also von 0 - 13  ... oder hab ich da jetzt was verplant?
Ist im Prizip aber auch erstmal egal  



> Nunja wenn der Client aber nicht mehr antwortet, klappt das mit deinem Timestamps hin und herschicken auch nicht.
> Am besten wäre es wenn der Client jeweils einen Timer hätte und alle 10 Sekunden einen Timestamp an den Server schickt und der Server in einem Thread immer mal wieder alle Clients durchgeht und schaut ob auch alle noch Timestamps schicken und diese ansonsten rausschmeisst.


Im Prinzip hatte ich es genauso vor. Nur das schicken eines Timestamps vom Clienten aus ist problematisch. Ich spreche dieses Javaprogramm über einen Flash-Clienten an.
Bei Flash ist man ja gezwungen mit AS zu arbeiten. Und AS hat leider keine Möglichkeit Timestamps zu holen. Ich könnte einen Timestamp zwar holen, indem ich über Flash eine PHP-Seite auslese,aber das ist zu Resourcenverschwendend und stellt außerdem eine Sicherheitslücke dar.

Also dachte ich mir, ich hole den Timestamp vom Server, indem ich die Methode TP() aufrufe. Diese sendet dann ja den Timestamp des Servers an den Clienten.
Und dieser Client sendet darauf hin den gerade bekommenen Timestamp zurück an den Server. Der Server speichert diesen Timestamp. Das geschieht jede Sekunde. Der alte Timestamp des Clienten wird am Server jedesmal überschrieben und bliebt so aktuell. Und ab da läuft alles so, wie du es geschrieben hast. Wenn der Client offline geht, kommen keine Timestamps mehr an. D.h der Timestamp des Clienten "veraltet". Und das kann ich ja überprüfen...




> wenn [...]der Server in einem Thread immer mal wieder alle Clients durchgeht und schaut ob auch alle noch Timestamps schicken und diese ansonsten rausschmeisst.


Wie du bereits gemerkt hast, bin ich was Java angeht kein großer Held . Sondern programmiere Java mit den Kenntnissen aus anderen Programmiersprachen ^^.
Was Threads sind weiß ich zwar, aber um das zu realisieren bräuchte ich doch immernoch diesen verdammten Timer oder soll ich einfach einen Thread erstellen wo ich den Vergleich in einer Endlosschleife laufen lasse? (Das würde ich noch hinbekommen ^^  )

Danke und Gruß
Max


----------



## zeja (12. April 2007)

Dann mach doch das so wie dus machen wolltest halt mit einem Thread.


```
Thread thread = new Thread("TimeOutCheck"){
   public void run(){
      ... hier der Code zum prüfen ...
     Thread.sleep(1000); //1s schlafen legen damit andere auch ne Chance haben
   }
};
thread.start(); //Thread starten. Niemals run aufrufen, sonst ist läuft es nicht als Thread
```

Die Zahl mit der man ein Array anlegt steht für die Anzahl der Elemente. Bei 13 sinds 13 Element mit einem Index von 0 bis 12.


----------



## MettMax (12. April 2007)

Arghhhh! Ich liebe dich !  

Das scheint gut zu funktionieren! Habs jetzt nur getestet in dem ich einfach mal eine Variable jede Sekunde incrementiert habe, aber das läuft einwandfrei.
Ich werde das heute Abend mal fertig machen, und danach mal eine Code-Reinigung vornehmen ..


Vieeelen Dank auf jedenfall!!

Lg Max



> Bei 13 sinds 13 Element mit einem Index von 0 bis 12.


Ok, ich hab nichts gesagt


----------

