server auf verfügbarkeit prüfen

Schlicki

Grünschnabel
Hallo erstmal allerseits^^

Ich hab nen Java Chat geschrieben und soweit funktioniert auch alles.
Der Aufbau ist Folgender: Ein Server der auf nen Stream wartet und den dann an alle verbundenen Clients sendet.

Das Problem das ich habe kann 2mal auftreten:
Einmal wenn der Client an den Server sendet und einmal wenn der Server die Nachricht wieder an die Clients verteilt.
Es kann ja theoretisch sein, dass der Sevrer bzw der Client (eher der Client) einfach nicht verfügbar ist und dann der Sender ne exception wirft. Allerdings beendet sich dann der Server bzw der Client und das hat nen absoluten Absturz des Chats zur Folge.

Jetzt die Frage: Gibt es ne möglichkeit zu testen ob ein Computer verfügbar ist und wenn ja ob auf dem der Client bzw der Server läuft?

gz Johannes
 
Zuletzt bearbeitet:
*grins* wie wärs mit vernünftigem ExceptionHandling? Fang die entsprechende Exception und Trigger einen Retry - vielleicht 2 oder 3 mal, nach ner kurzen Wartepause. Was dann genau passiert ist eine fachliche Entscheidung, die du treffen musst. Das technische Mittel allerdings heißt einfach nur ExceptionHandling ;)

REINHAUN!
 
Also try und catch meinst du oder?
Das mach ich schon alles, aber wie mach ich weiter dass er zb wieder ne Schleife startet, nachdem er im catch bereich war?
bin da nach einigen versuchen mit meinem Latein am Ende^^

gz
 
zum beispiel die Anfrage in eine Methode packen und diese Methode halt im catch block wieder rufen. Vorher nen Zähler inkrementieren und den vor dem erneuten Rufen auswerten.

Gruß
Ollie
 
Hallo,

von Hand könnte man sowas etwa so machen:
Java:
/**
 * 
 */
package de.tutorials;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Random;

/**
 * @author Thomas.Darimont
 * 
 */
public class RetryExample {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		RetryAwareInvocationHandler invocationHandler = new RetryAwareInvocationHandler();
		invocationHandler.setTarget(new BusinessService());
		invocationHandler.setMaxRetries(3);
		invocationHandler.setRetryIfExceptionOccurs(true);
		IBusinessService businessService = (IBusinessService) Proxy
				.newProxyInstance(RetryExample.class.getClassLoader(),
						new Class<?>[] { IBusinessService.class },
						invocationHandler);

		System.out.println(businessService.businessOperation("xxx"));
	}

	static interface IBusinessService {
		String businessOperation(String args);
	}

	static class BusinessService implements IBusinessService {

		Random random = new Random();

		@Override
		public String businessOperation(String args) {
			if (random.nextInt(10) < 7) {
				throw new RuntimeException(
						"Service not available at the moment...");
			}
			return "#" + args;
		}
	}

	static class RetryAwareInvocationHandler extends
			TargetAwareInvocationHandler {

		int maxRetries;

		/**
		 * @return the maxRetries
		 */
		public int getMaxRetries() {
			return maxRetries;
		}

		/**
		 * @param maxRetries
		 *            the maxRetries to set
		 */
		public void setMaxRetries(int maxRetries) {
			this.maxRetries = maxRetries;
		}

		boolean retryIfExceptionOccurs;

		/**
		 * @return the retryIfExceptionOccurs
		 */
		public boolean isRetryIfExceptionOccurs() {
			return retryIfExceptionOccurs;
		}

		/**
		 * @param retryIfExceptionOccurs
		 *            the retryIfExceptionOccurs to set
		 */
		public void setRetryIfExceptionOccurs(boolean retryIfExceptionOccurs) {
			this.retryIfExceptionOccurs = retryIfExceptionOccurs;
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			int tries = 0;
			while (tries++ < maxRetries) {
				try {
					return super.invoke(proxy, method, args);
				} catch (Throwable throwable) {
					if (!retryIfExceptionOccurs) {
						break;
					}
					Throwable targetException = throwable;
					if(throwable instanceof InvocationTargetException){
						targetException = ((InvocationTargetException)throwable).getTargetException();
					}
					System.out.println("Retry: " + method
							+ " because of exception: " + targetException);

				}
			}

			throw new RuntimeException(
					String
							.format(
									"Maximum number [%s] of retries reached for execution of %s @ %s",
									maxRetries, method, target));
		}
	}

	static class TargetAwareInvocationHandler implements InvocationHandler {

		Object target;

		/**
		 * @return the target
		 */
		public Object getTarget() {
			return target;
		}

		/**
		 * @param target
		 *            the target to set
		 */
		public void setTarget(Object target) {
			this.target = target;
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			return method.invoke(getTarget(), args);
		}
	}
}

... oder das ganze in einen AspectJ / Spring AOP Aspect gießen.

Gruß Tom
 
OK...Vielen Dank erstmal...also der Client kann jetzt verbinden und verabschiedet sich nicht wenn der Server nicht verfügbar ist^^

Ich hatte auch schon ein nächstes serverseitiges Problem und zwar:
mehrere Client senden an den Server und der Server verteilt alle eingehenden Nachrichten an alle Clients. Das geschieht über ein Thread für jede Nachricht, die der Server wieder versendet. Das praktische daran ist, dass der Server nicht abstürzt wenn ein Client auf einmal nicht mehr verfügbar ist, sondern nur das Thread stürzt ab, was nicht weiter schlimm wäre...^^
Alle User an die der Server sendet stehen in einem dynamischen Array. Ich will irgendwie schaffen, dass der Server die Clients die nicht mehr verfügbar sindaus der Liste der User löscht und nicht immer ein Thread startet, das terminiert,, weil ein User nicht mehr verfügbar ist. Ist es möglich über eine Abfrage die Art des Beendens eines Threads herauszubekommen oder is das einzige was über Threads hearuszubekommen ist, das was Thread.State hergibt

mfG Johannes
 

Neue Beiträge

Zurück