1
2
3
4
5
6
7 package org.sourceforge.jvb3d.Network;
8
9 import java.io.IOException;
10 import java.net.InetSocketAddress;
11 import java.util.Observable;
12 import java.util.Observer;
13 import java.util.logging.Logger;
14
15 /***
16 * @author Łukasz Krzyżak
17 *
18 * klasa odpowiedzialna za komunikowanie się klienta z serwerem. Sprawdza
19 * poprawność otrzymywanych pakietów, wysyła update, łączy z serwerem.
20 */
21 public class ServerData implements Observer {
22 NetworkSender networkSender;
23
24 private String connectData;
25
26 private long seqNumber = 0;
27 private long sendSeqNumber = 1;
28
29 private long lastPacketReceived = System.currentTimeMillis();
30
31 private InetSocketAddress serverAddress;
32 private Logger fLogger = Logger.getLogger("ServerData");
33
34 /***
35 * czas, po którym stwierdzamy, że serwer jest rozłączony jesli nie dostaliśmy od niego żadnego pakietu
36 */
37 public static final long serverTimeout = 1000;
38
39 private NetworkClientFacade clientFacade;
40
41 /***
42 * tworzy wymagane obiekty (NetworkSender)
43 */
44 public ServerData() {
45 networkSender = new NetworkSender();
46 clientFacade = NetworkClientFacadeHolder.getNetworkFacade();
47 }
48
49 /***
50 * próbuje połączyc się z serwerem. Wysyła pakiet join na adres podany w
51 * parametrze, a następnie czeka, aż klient otrzyma pakiet connect - wtedy
52 * metoda update spowoduje wznowienie wykonywania i zwrócenie wartości
53 * otrzymanych w pakiecie.
54 *
55 * @param server
56 * adres serwera
57 * @return ID avatara powiązanego z tym klientem
58 * @throws IOException
59 * jeśli coś poszło źle
60 * TODO jeśli nie otrzymamy pakietu connect - wisimy na wieki
61 * TODO join zwraca stringa - docelowo będzie coś większego
62 */
63 public synchronized String join(InetSocketAddress server)
64 throws IOException {
65 JoinPacket joinPacket = new JoinPacket();
66 networkSender.send(joinPacket, server.getAddress(), server.getPort());
67
68 try {
69 wait();
70 } catch (InterruptedException e) {
71 }
72
73 serverAddress = server;
74 return connectData;
75 }
76
77 /***
78 * obsługuje pakiety otrzymane z sieci. Jeśli to pakiet connect - zapisuje
79 * zapisane w nim dane, i notyfikuje główny wątek. Jeśli to pakiet update -
80 * sprawdza numer SEQ, aktualizuje czas, po czym wywołuje odpowiednią metodę
81 * z fasady
82 * TODO ładniejsza obsługa wyjątków
83 * @param arg0 referencja do bufora
84 * @param arg1
85 */
86 public synchronized void update(Observable arg0, Object arg1) {
87 try {
88 Packet recvPacket = ((ReceivedPacketBuffer) arg0).getNextPacket();
89 if (recvPacket instanceof ConnectPacket) {
90 connectData = ((ConnectPacket) recvPacket).getAvatarId();
91 notify();
92 } else if (recvPacket instanceof UpdatePacket) {
93
94 if (validatePacket((UpdatePacket) recvPacket))
95 clientFacade.forwardUpdate((UpdatePacket)recvPacket);
96 else
97 fLogger.warning("Serwer otrzymał pakiet ze złym numerem seq");
98 }
99 } catch (Exception e) {
100 e.printStackTrace();
101 }
102 }
103
104 private boolean validatePacket(UpdatePacket update) {
105
106 if (update.getSeqNumber() <= seqNumber)
107 return false;
108 seqNumber = update.getSeqNumber();
109 lastPacketReceived = System.currentTimeMillis();
110 return true;
111 }
112
113 /***
114 * wysyła dane przekazane w parametrze do serwera, sprawdza timeout serwera
115 * @param updateData dane do przesłania
116 * @throws TimeoutException gdy wystąpił timeout serwera
117 * @throws IOException gdy wystapił błąd wysyłania pakietu
118 */
119 public void sendUpdate(byte[] updateData) throws TimeoutException, IOException{
120 if(System.currentTimeMillis() - lastPacketReceived > serverTimeout) throw new TimeoutException(serverAddress);
121
122 UpdatePacket updatePacket = new UpdatePacket();
123 updatePacket.setSeqNumber(sendSeqNumber++);
124 updatePacket.setUpdateData(updateData);
125 networkSender.send(updatePacket, serverAddress.getAddress(), serverAddress.getPort());
126 }
127
128 /***
129 * brzydka funkcja do testów
130 * @param address
131 */
132 void setServerAddress(InetSocketAddress address) {
133 serverAddress = address;
134 }
135 }