Countdownfunktion gesucht

  • Themenstarter Themenstarter ehrich45
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
also ich kann das ja mal kurz erklären.

ich kriege per udp verbindung lognachrichten geschickt. alle 20 sekunden oder so gibts ne nachricht von einer maschine die mir damit signalisiert das sie "online" ist.

die maschine schickt dabei jedes mal ihre maschinen id sowie ihren status ( online,error) mit.

ich möchte jetzt wenn eine nachricht ankommt in meiner datenbank den status der maschine setzen.
wenn man länger als 20 sekunden nichts mehr gehört hat geht sie offline. ansonsten soll der timer wieder hochgesetzt werden und ggf der status verändert werden.

das ganze sollte mit 10-20 maschinen gehen.

gestartet wird das ganze hier :

Code:
  if(level.equals("<199>")){
		   level = "Machine-Online";
		  System.out.println("Maschine: "+SsenderId+","+Stype+" online");
//		SqlData.setMachineOnline(SsenderId);
		  
		CopyOfCheckOnline CheckOnline = new CopyOfCheckOnline(SsenderId,Status);
		
		// System.out.println("status: "+Status);
		 
			  try {CheckOnline.timer(SsenderId,Status); } 
			  
			  catch (InterruptedException e) {e.printStackTrace();}

	   }
Der code befindet sich in der klasse die die nachricht empfängt und in ihre einzelheiten aufteilt. dann übergibt sie der Checkonlineklasse die maschinen-id sowie den empfangenen status.

dann soll ein thread gestartet werden der 20 sekunden runter zählt. wenn die gleiche maschine wieder eine nachricht schickt wird der status geändert, und die zeit wieder auf 20 gesetzt.

das ganze fuer jede maschine einzeln.

so sollte das ganze aussehen🙂


da ich nicht so die ahnung von threadprogrammirerung habe versuche ich einfach das umzusetzen was jPat mir immer sagt.
aber anscheind klappt das nicht so ganz .. zumidest kommen wir immer einen schritt weiter.

es muss halt gelöst werden... egal wie.. und würde ich euch nicht haben würde ich das glaube ich nie hinbekommen.


EDIT:

zu pukt 4: da gebe ich dir recht. das macht keinen sinn.. ist mir aber nicht aufgefallen weil es funktioniert hat. danke dir.
 
Also:

Main Klasse:
diese Klasse dient NUR zum erstellen deiner Verwaltung, UND zum Fragen in der Verwaltung, ob Irgendwas Mit den Threads ist. sonst NIX.
Code:
class Main {

public static void main(String args){
Verwaltung v = new Verwaltung();
v.init();
// hier wird die Verwaltung bemüht, um in der Liste zu schauen, was mit den Thread grad so los ist. (Jede sekunde)
while(true){
try{
Thread.sleep(1000); //Warte 1 secunde (hat nix mit deinen Threads zu tun ist für den MAIN-THREAD!!) 
v.ckeckThreads();
}catch(Exception e){syso(e.printStackTrace()) }
}
}
}

deine Verwaltungsklasse dient zum Verwalten der Threads und natürlich zum starten der Threads.
Code:
class Verwaltung {
Hashtable<String,CheckOnline> threadTable = new Hashtable<String,CheckOnline>();
ArrayList<ReturnSqlMachineStatus> Statusdaten;
Thread t[]; 

// in dieser Methode werden ALLE Threads gestartet!! und in die HT geschrieben. Diese Methode solltest du für weiter überprüfungen NICHT ändern.
public void init(){ 
 Statusdaten = SqlData.getSqlDataStatus();
 t[] = new Thread[Statusdaten.size()];  
      for(int p=0;p<Statusdaten.size();p++){                                 
              t[p] = new Thread(new Timer(Statusdaten.get(p).m_sender_id,Status_)); 
              threadTable .put(Statusdaten.get(p).m_sender_id,t[p]);   
              t[p].start();
}
public void ckeckThreads(){

for (int i =0, i<Statusdaten.size(); i++){
if ( threadTable.get(Statusdaten.get(p).m_sender_id) == null ) {sysout("Der existiert gar nicht:  "+ i)}
else if ( threadTable.get(Statusdaten.get(p).m_sender_id).runnable=false ) {sysout("Der ist fertig!!:  "+ i)}
if ( threadTable.get(Statusdaten.get(p).m_sender_id).runnable==truel ) {sysout("der läuft noch:  "+ i)}
}



}

}

deine Checkonline Klasse erweitert die Thread-Klasse. In diesem beispiel wartet jeder Thread 60 sekunden, macht dann die SqlData.delMachineOnline() Methode und geht zu ende.

Code:
class CheckOnline extends Thread{
int time = 0;
boolean running = false
public void start(){
          super.start();
            if (time <= 10 || running==false){
               time = 10;
               running = true;
            }
         }

      public void run(){
          
         while (running){
          
             sleepOneSec();
              
             if (time < 1 ){
                try {SqlData.delMachineOnline(SenderId); running=false;  } catch (SQLException e) {e.printStackTrace();}       
             }
         }
      } 
private void sleepOneSec( ){
         try
         {
             Thread.sleep(1000);
             time--;
             System.out.println("Time: "+time);
             if (time == 0 ){
                running = false;
             }
      }
      catch (Exception e) {}

      } 

}

Du mußt dir klarmachen, das der Mainthread für dich die Aufgabe übernehmen muß, in die Verwaltung zu schauen, was mit den Threads ist.

In deinem Code wird soll ja für Jeden CheckOnlineThread ein Weiterer Thread zur Prüfung des Status erschaffen werden. Das ist eine Ebene zu Tief ....

Ich hoffe es klappt nun mit dem Verständnis. Der code ist nicht getestet, sollte aber von der Stuktur funktionieren.

Gruß
 
@ jPat echt vielen Dank fuer deine Bemühungen.

versuche das grade alles umzuschreiben, weil irgednwie entspricht das noch nicht so ganz dem sinn meiner vorstelleung. oder ich habs nicht verstanden 🙂

weil ja nicht alle threads gestartet werden sollen. sondern nur der von dem ich per socket ne nachricht bekomme und der dann den thread anstoßen soll. (der status ist dabei variable)

also zb.

alle threads aus. dann kommt ne message mit (Id=25696,Status=3) --> dann soll der thread gestartet werden, timer soll runter laufen. kommt nacht 5 sekunden jetzt aber schon wieder ne neue message (Id=25696,Status=2)
soll nur der Status geändert werden + zeit wieder hochgesetzt werden und dann wieder runterlaufen.

das ganze soll dann bei allen maschinen so laufen.

falls dann bsp 30 sekunden gar keine message kam, wird der status automatisch auf 0 gesetzt ( bei der maschine die keine meldung mehr bekommen hat)

ich versuche das jetzt so umzubauen. falls du noch tipps hast. immer her damit 🙂

vielen dank schonmal.

hier ist noch der code mit dem ich die messages empfange. vllt hilft das ja weiter.


Code:
public class GetLogData extends Thread implements Runnable { 
	
	
	static String SenderId = null;
  
	public void startLog(){
		Thread t1 = new Thread( new GetLogData("36965")  ); 
        t1.start(); 
	}
	
	public GetLogData(String ssenderId ){ 
		 this.SenderId = ssenderId;
		} 
	
    public void run (){ 
      try{     
           byte  buffer[] = new byte[0xffff]; 

          DatagramPacket packet = new DatagramPacket(buffer, buffer.length); 
          DatagramSocket socket = new DatagramSocket(SqlData.getPort()); 
          
           while (true) 
            { 
            socket.receive(packet); 

            int    len      = packet.getLength(); 
                    buffer   = packet.getData(); 
                     
            String   frage    = new String(buffer, 0, len); 

            System.out.println("Anfrage von: " + packet.getAddress() + 
                                  " am Port " + packet.getPort() + " empfangen: " + frage ); 

            SplitLdata.Split(packet.getAddress(),packet.getPort(),frage);
        	}
          } 
       catch ( Exception e ) 
          { 
            System.out.println("Fehler: " + e); 
          } 
   }
}

In SplitData wird die message aufgesplittet und "senderId" sowie "status" an die threadfunktion übergeben.

EDIT: bin auch gern fuer andere lösungen offen. also falls das ganze ohne threads oder sowas geht. dann nehm ich aucg gerne solche vorschläge an 🙂 (threads mag ich seit diesem thema nicht mehr 🙂 )

vielen dank !!
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben