# Grundlegende Design-Frage zu Webservices



## 555Nase (23. Jan 2008)

Hallo,

wie würdet Ihr folgendes Problem implementieren:

- Eine bestimmte Anzahl an Webservices schickt eine zufällige Integer-Zahl an einen Webservice Server
- Als Antwort schickt der der Server die Summe der Zahlen an alle Clients

Voraussetzung:
- Kein Client weiß, wie viele andere Clients es noch gibt
- Der Server kennt die Anzahl der Client.
- Sobald der letzte seine Zahl übermittelt hat, schickt der Server unmittelbar die Antwort


Danke


----------



## Niki (23. Jan 2008)

Soll der Server die Antworten asynchron schicken oder soll die service-Methode solange blockieren bis alle Clients ihre Zahlen geschickt haben?


----------



## 555Nase (23. Jan 2008)

Danke,

der Service muss warten, bis alle Clients ihre Zahl geschickt haben, sonst kann der nicht die korrekte Summe addieren.


----------



## Niki (23. Jan 2008)

Wenn die Methode blockieren soll würd ichs so machen:


```
private static final Object MONITOR = new Object();
private static final int anzahlClients = 5;

private static final List<Integer> zahlen = new ArrayList<Integer>();

public int getSum(int random){
  synchronized(MONITOR){
    zahlen.add(random);
    if(zahlen.size() < anzahlClients){
      try{
        MONITOR.wait();
      }catch(InterruptedException ex){
      }
    } else {
      MONITOR.notifyAll();
    }
  } 
  int sum = 0;
  for(Integer i : zahlen)
    sum+=i;
  return sum;
}
```


----------



## Guest (23. Jan 2008)

Vielen Dank, genau so hab ich mir das vorgestellt!!!!


----------



## 555Nase (24. Jan 2008)

Hallo,

nochmals vielen Dank für den obigen Code.

Noch eine ganz kurze Nachfrage:

Angenommen, es nicht darum , die Summe zu berechnen, sondern die Antwort des Webservices soll einfach nur die Reihenfolge des Aufrufs sein, also

1. Client bekommt eine 1 zurück
2. Client bekommt eine 2 zurück
3. Client bekommt eine 3 zurück
usw.

natürlich erst, nachdem anzahlClients erreicht ist.

Meine Idee bisher: Ich spalte das in 2 Methoden auf. Jeder Client schickt eine Zufallszahl mit der ersten Methode. Die Zahl wird dann in eine Liste geschrieben.

Mit der zweiten methode übergibt der Client erneut seine Zufallszahl und es wird die Stelle zurückgegeben, an der die Zufallszahl steht.

Könnte man das auch in eine Methode setzten?

Danke


----------



## 555Nase (24. Jan 2008)

Nachtrag: Natürlich könnte man die gesamte Liste zurückgeben, allerdings wird die bei vielen Clients recht groß


----------



## Niki (24. Jan 2008)

Naja, Zufallszahlen die die Clients generieren müssen ja nicht umbedingt eindeutig sein, du kannst dir eine eindeutige ID zuerst vom Server generieren lassen, ist aber nicht notwendig, wenn du wissen willst an welche Stelle dein Client war genügt eine statische Variable:

```
private static final Object MONITOR = new Object();
private static final int anzahlClients = 5;

private static final List<Integer> zahlen = new ArrayList<Integer>();

private static int counter = 0;

public int getSum(int random){
  int num = 0;
  synchronized(MONITOR){
    counter++;
    num = counter;
    zahlen.add(random);
    if(zahlen.size() < anzahlClients){
      try{
        MONITOR.wait();
      }catch(InterruptedException ex){
      }
    } else {
      MONITOR.notifyAll();
    }
  }
  int sum = 0;
  for(Integer i : zahlen)
    sum+=i;
  return num;
}
```


----------



## 555Nase (24. Jan 2008)

Danke, funktioniert. Hatte zunächst die Befürchtung, daß er an alle die letzte Zahl zurückgibt...


----------



## 555Nase (24. Jan 2008)

Hallo,

es gibt ein kleines Problem: Leider funktionieren all diese Methoden nur mit 2 und nicht mit mehr Clients. Ich hatte das vorher auch nur mit 2 Methoden getestet. Weißt Du, woran das liegen könnte? Ich teste sie mit der Webservice-Testfkt. aus Glassfish+Netbeans.

Danke


----------



## Niki (24. Jan 2008)

Pfuh, gib mir einen Moment Zeit, dann kann ich mir schnell ein Web-Service basteln...
Ich geb dir bescheid wenn ich etwas heraus finden konnte bzw. ob es bei mir klappt.


----------



## Niki (24. Jan 2008)

Bei mir funktioniert die Methode zum Aufsummieren. Mit Tomcat und Axis1.4.

Kann dir daher leider nicht weiter helfen.

Schönen Abend, ich bin jetzt dann mal weg....


----------



## Niki (25. Jan 2008)

Und, Fehler gefunden? Hast du bei anzahlClients vielleicht 2 zugewiesen? Das würde natürlich erklären warum es nur bei 2 geht!


----------



## 555Nase (25. Jan 2008)

Danke der nachfrage. In der Tat klappt es auch mit mehr als 2 Clients. Ich weiß ehrlich nicht genau woran es lag, kann es sein daß alle Var "static" sein müssen?

Vielleicht mal ganz kurz zu meinem Problem. Es geht in meinem Projekt darum, ein Gebotsystem zu erstellen. Jeder Client gibt ein Gebot ab und der Gewinner erhält den Zuschlag. Deswegen suchte ich auch eine Lösung, bei der erst nach Abgabe von Informationen durch alle Clients alle Clients die Antwort erhalten.  Im folgenden soll nur Client 2Gewinner sein, alle anderen Verlierer. Meine Methode sieht so aus:

```
private static boolean Won=true;
 private static int Counter = 0;
     @WebMethod(operationName = "Winner")
    public boolean Winner() {
        int num = 0;
        //TODO write your implementation code here:
        synchronized (MONITOR) {
            Counter++;
            num = Counter;
            if (num==2) {Won=true;} else {Won=false;}
            if (num < anzahlClients) {
                try {
                    MONITOR.wait();
                } catch (InterruptedException ex) {
                }
            } else {
                MONITOR.notifyAll();
            }
        }

        return Won;

    }

Was ich jetzt nicht verstehe, wieso alle Clients false erhalten?

Nochmals vielen Dank!
```


----------



## 555Nase (25. Jan 2008)

äh, sorry


```
private static int Counter = 0;
  private static boolean Won=true;
     @WebMethod(operationName = "Winner")
    public boolean Winner() {
        int num = 0;
        //TODO write your implementation code here:
        synchronized (MONITOR) {
            TruckCounter++;
            num = Counter;
            if (this.Counter==2) {Won=true;} else {Won=false;}
            if (num < anzahlClients) {
                try {
                    MONITOR.wait();
                } catch (InterruptedException ex) {
                }
            } else {
                MONITOR.notifyAll();
            }
        }

        return Won;

    }
```


----------



## 555Nase (25. Jan 2008)

nochmals sorry


```
private static int Counter = 0;
  private static boolean Won=true;
     @WebMethod(operationName = "Winner")
    public boolean Winner() {
        int num = 0;
        //TODO write your implementation code here:
        synchronized (MONITOR) {
            Counter++;
            num = Counter;
            if (this.Counter==2) {Won=true;} else {Won=false;}
            if (num < anzahlClients) {
                try {
                    MONITOR.wait();
                } catch (InterruptedException ex) {
                }
            } else {
                MONITOR.notifyAll();
            }
        }

        return Won;

    }
```


----------



## 555Nase (25. Jan 2008)

Hat sich erledigt, diie Boolean-Var muß in die Methode...


----------

