Server.java 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. package Connection.socket;
  2. import java.net.*;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import java.util.concurrent.TimeUnit;
  6. import classes.HolonElement;
  7. import classes.HolonObject;
  8. import ui.controller.Control;
  9. import java.io.*;
  10. public class Server implements Runnable{
  11. private ServerSocket serverSocket;
  12. private Socket clientSocket;
  13. private DataOutputStream out;
  14. private DataInputStream in;
  15. private boolean stopped = false;
  16. private boolean connection = false;
  17. private ui.view.Console console;
  18. private HolonObject observed;
  19. private HolonObjectModel model;
  20. private Control control;
  21. public Server(int port, ui.view.Console console, HolonObject observed, Control control) throws IOException {
  22. this.observed = observed;
  23. this.console = console;
  24. this.control = control;
  25. //Bind Port
  26. serverSocket = new ServerSocket(port);
  27. //Wait for Connection
  28. Thread serverThread = new Thread(this);
  29. serverThread.start();
  30. }
  31. public void stopServer() throws IOException {
  32. stopped = true;
  33. stopConnection();
  34. if(serverSocket != null)serverSocket.close();
  35. console.println("Server Closed");
  36. }
  37. private void stopConnection() throws IOException {
  38. connection = false;
  39. if(in != null)in.close();
  40. if(out != null)out.close();
  41. if(clientSocket != null)clientSocket.close();
  42. }
  43. @Override
  44. public void run() {
  45. while(!stopped) {
  46. try {
  47. //Wait for new Connection
  48. console.println("Wait for Connection..");
  49. clientSocket = serverSocket.accept();
  50. console.println("Connection from " + clientSocket.getInetAddress() + ":" + clientSocket.getPort());
  51. connection = true;
  52. out = new DataOutputStream(clientSocket.getOutputStream());
  53. in = new DataInputStream(new BufferedInputStream(clientSocket.getInputStream()));
  54. if(observed == null) stopConnection();
  55. createModel();
  56. Thread updateThread = new Thread(new UpdateLoop());
  57. updateThread.start();
  58. //InputLoop
  59. try {
  60. inputLoop();
  61. }catch(EOFException e){
  62. console.println("Connection Closed");
  63. }
  64. stopConnection();
  65. }
  66. catch(SocketException e){
  67. //ServerSocket is closed
  68. stopped = true;
  69. }
  70. catch (IOException e) {
  71. e.printStackTrace();
  72. }
  73. connection = false;
  74. }
  75. }
  76. private void inputLoop() throws IOException {
  77. while (connection) {
  78. //WaitForInput
  79. byte inputByte = in.readByte();
  80. //UpdateHoleg
  81. if (inputByte == Command.SetAmount) {
  82. if(observed == null) stopConnection();
  83. console.println("Res: [" + inputByte + "] -> SetAmount");
  84. int index = in.readInt();
  85. int amount = in.readInt();
  86. observed.getElements().get(index).setAmount(amount);
  87. }else if (inputByte == Command.SetEnable) {
  88. if(observed == null) stopConnection();
  89. console.println("Res: [" + inputByte + "] -> SetEnable");
  90. int index = in.readInt();
  91. boolean enabled = in.readBoolean();
  92. observed.getElements().get(index).setActive(enabled);
  93. }else if (inputByte == Command.IncreaseAmount) {
  94. if(observed == null) stopConnection();
  95. console.println("Res: [" + inputByte + "] -> IncreaseAmount");
  96. int index = in.readInt();
  97. HolonElement ele = observed.getElements().get(index);
  98. ele.setAmount(ele.getAmount()+1);
  99. }else if (inputByte == Command.DecreaseAmount) {
  100. if(observed == null) stopConnection();
  101. console.println("Res: [" + inputByte + "] -> DecreaseAmount");
  102. int index = in.readInt();
  103. HolonElement ele = observed.getElements().get(index);
  104. ele.setAmount(ele.getAmount()-1);
  105. } else{
  106. console.println("Res: [" + inputByte + "] -> unknown");
  107. }
  108. control.calculateStateAndVisualForCurrentTimeStep();
  109. control.updateCanvas();
  110. control.getGui().triggerUpdateController(null);
  111. }
  112. }
  113. private void createModel() {
  114. model = new HolonObjectModel();
  115. int index = 0;
  116. for(HolonElement ele :observed.getElements()) {
  117. model.add(ele, index++);
  118. }
  119. }
  120. public class UpdateLoop implements Runnable{
  121. public UpdateLoop(){
  122. }
  123. @Override
  124. public void run() {
  125. sendUpdate();
  126. while(!stopped && connection) {
  127. if(checkForUpdates()){
  128. sendUpdate();
  129. }else {
  130. waitOneSecond();
  131. }
  132. }
  133. }
  134. private void waitOneSecond() {
  135. //wait one second
  136. try {
  137. TimeUnit.SECONDS.sleep(5);
  138. } catch (InterruptedException e) {
  139. }
  140. }
  141. private boolean checkForUpdates() {
  142. //TODO Delete And CheckforUpdatesReal
  143. //-->Test
  144. waitOneSecond();
  145. createModel();
  146. //<--Test
  147. return true;
  148. }
  149. private void sendUpdate() {
  150. try {
  151. if(observed == null) stopConnection();
  152. console.println("Send: [" + Command.Update + "] -> Update");
  153. out.writeByte(Command.Update);
  154. out.writeInt(model.size());
  155. for(HolonElementWrapper wrapper : model.getElements()) {
  156. out.writeUTF(wrapper.name);
  157. out.writeInt(wrapper.amount);
  158. out.writeFloat(wrapper.energy);
  159. out.writeBoolean(wrapper.enabled);
  160. }
  161. } catch (IOException e) {
  162. if(connection)console.println(e.getMessage());
  163. }
  164. }
  165. }
  166. public class Command {
  167. //InputCommands
  168. public static final int SetAmount = 10;
  169. public static final int SetEnable = 11;
  170. public static final int IncreaseAmount = 12;
  171. public static final int DecreaseAmount = 13;
  172. //UpdateResiveCommands
  173. public static final int Update = 20;
  174. }
  175. public class HolonObjectModel {
  176. //Field
  177. private List<HolonElementWrapper> elements;
  178. private String holonObjectName;
  179. //constructor
  180. public HolonObjectModel(){
  181. elements = new ArrayList<HolonElementWrapper>();
  182. }
  183. public void add(HolonElement ele, int index ) {
  184. String name = ele.getEleName();
  185. int amount =ele.getAmount();
  186. float energy = ele.getEnergyPerElement();
  187. boolean enabled = ele.isActive();
  188. elements.add(new HolonElementWrapper(name, amount, energy, enabled, index));
  189. }
  190. public int size() {
  191. return elements.size();
  192. }
  193. //Getter/Setter
  194. public List<HolonElementWrapper> getElements() {
  195. return elements;
  196. }
  197. public String getHolonObjectName() {
  198. return holonObjectName;
  199. }
  200. public void setHolonObjectName(String holonObjectName) {
  201. this.holonObjectName = holonObjectName;
  202. }
  203. }
  204. public class HolonElementWrapper{
  205. public int index;
  206. public String name;
  207. public int amount;
  208. public float energy;
  209. public boolean enabled;
  210. public HolonElementWrapper(){
  211. }
  212. public HolonElementWrapper(String name, int amount, float energy, boolean enabled, int index){
  213. this.name = name;
  214. this.amount = amount;
  215. this.energy = energy;
  216. this.enabled = enabled;
  217. }
  218. @Override
  219. public boolean equals(Object obj) {
  220. if (obj == this) {
  221. return true;
  222. }
  223. if (!(obj instanceof HolonElementWrapper)) {
  224. return false;
  225. }
  226. HolonElementWrapper element = (HolonElementWrapper) obj;
  227. return this.name == element.name &&
  228. this.amount == element.amount &&
  229. this.energy == element.energy &&
  230. this.enabled == element.enabled;
  231. }
  232. }
  233. }