PageRenderTime 42ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/MobileLuaLive/JavaServer/src/mosync/mobilelualiveserver/Server.java

http://mobilelua.googlecode.com/
Java | 472 lines | 367 code | 57 blank | 48 comment | 30 complexity | fcc6ac8c5d96161b0745cfacf4670b67 MD5 | raw file
Possible License(s): LGPL-3.0
  1. package mosync.mobilelualiveserver;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.io.ObjectInputStream;
  5. import java.io.ObjectOutputStream;
  6. import java.io.OutputStream;
  7. import java.net.ServerSocket;
  8. import java.net.Socket;
  9. import java.util.ArrayList;
  10. public class Server extends Thread
  11. {
  12. private boolean mRunning = false;
  13. private ArrayList<ClientConnection> mClientConnections;
  14. private ClientSocketAcceptor mClientAcceptor;
  15. private ArrayList<EditorConnection> mEditorConnections;
  16. private EditorSocketAcceptor mEditorAcceptor;
  17. public Server()
  18. {
  19. mRunning = false;
  20. mClientConnections = new ArrayList<ClientConnection>();
  21. mClientAcceptor = new ClientSocketAcceptor(55555, this);
  22. mEditorConnections = new ArrayList<EditorConnection>();
  23. mEditorAcceptor = new EditorSocketAcceptor(55556, this);
  24. }
  25. public void startServer()
  26. {
  27. if (!mRunning)
  28. {
  29. // Start my thread.
  30. start();
  31. mRunning = true;
  32. // Start acceptor threads.
  33. mClientAcceptor.start();
  34. mEditorAcceptor.start();
  35. }
  36. }
  37. private void stopServer()
  38. {
  39. // I am not running any longer.
  40. mRunning = false;
  41. // Stop acceptors.
  42. mClientAcceptor.close();
  43. mEditorAcceptor.close();
  44. }
  45. public void run()
  46. {
  47. worker();
  48. }
  49. private void worker()
  50. {
  51. while (mRunning)
  52. {
  53. // Wait for message (from client or editor connections).
  54. Message message = waitForMessage();
  55. Log.i("Server got message: " + message.getMessage());
  56. if ("ClientConnectionCreated".equals(message.getMessage()))
  57. {
  58. // Get connection object.
  59. ClientConnection connection = (ClientConnection) message.getObject();
  60. // Add connection.
  61. Log.i("Adding client connection: " + connection);
  62. mClientConnections.add(connection);
  63. // Start connection thread.
  64. connection.start();
  65. }
  66. else if ("ClientConnectionClosed".equals(message.getMessage()))
  67. {
  68. mClientConnections.remove(message.getObject());
  69. }
  70. if ("EditorConnectionCreated".equals(message.getMessage()))
  71. {
  72. // Get connection object.
  73. EditorConnection connection = (EditorConnection) message.getObject();
  74. // Add connection.
  75. Log.i("Adding editor connection: " + connection);
  76. mEditorConnections.add(connection);
  77. // Start connection thread.
  78. connection.start();
  79. }
  80. else if ("EditorConnectionClosed".equals(message.getMessage()))
  81. {
  82. mEditorConnections.remove(message.getObject());
  83. }
  84. else if ("CommandRunProgram".equals(message.getMessage()))
  85. {
  86. Log.i("Sending CommandRunProgram to clients");
  87. sendMessageToClients(message);
  88. }
  89. else if ("CommandRunSelection".equals(message.getMessage()))
  90. {
  91. Log.i("Sending CommandRunSelection to clients");
  92. sendMessageToClients(message);
  93. }
  94. else if ("MessageFromClient".equals(message.getMessage()))
  95. {
  96. Log.i("MessageFromClient: " + message.getObject());
  97. sendMessageToEditors(message);
  98. }
  99. else if ("CommandServerStop".equals(message.getMessage()))
  100. {
  101. stopServer();
  102. }
  103. else if("ServerAddressReceived".equals(message.getMessage()))
  104. {
  105. Log.i("ServerAddressReceived: " + message.getObject());
  106. sendMessageToEditors(message);
  107. }
  108. }
  109. }
  110. private void sendMessageToClients(Message message)
  111. {
  112. for (ClientConnection connection : mClientConnections)
  113. {
  114. Log.i("Sending Message: " + message + " to client connection: " + connection);
  115. connection.postMessage(message);
  116. }
  117. }
  118. private void sendMessageToEditors(Message message)
  119. {
  120. for (EditorConnection connection : mEditorConnections)
  121. {
  122. Log.i("Sending Message: " + message + " to editor connection: " + connection);
  123. connection.postMessage(message);
  124. }
  125. }
  126. /**
  127. * This is the server socket that accepts client
  128. * connections, that is, mobile devices listening
  129. * for commands to execute.
  130. */
  131. static class ClientSocketAcceptor extends Thread
  132. {
  133. private int mPort;
  134. private Server mServer;
  135. private ServerSocket mServerSocket;
  136. public ClientSocketAcceptor(int port, Server server)
  137. {
  138. mPort = port;
  139. mServer = server;
  140. }
  141. public void run()
  142. {
  143. try
  144. {
  145. worker();
  146. }
  147. catch (IOException e)
  148. {
  149. e.printStackTrace();
  150. }
  151. }
  152. /**
  153. * Call close to terminate the thread.
  154. */
  155. public void close()
  156. {
  157. if (null != mServerSocket)
  158. {
  159. try
  160. {
  161. mServerSocket.close();
  162. }
  163. catch (IOException e)
  164. {
  165. e.printStackTrace();
  166. }
  167. }
  168. }
  169. public void worker() throws IOException
  170. {
  171. mServerSocket = new ServerSocket(mPort);
  172. while (true)
  173. {
  174. Log.i("Waiting for client connection");
  175. Socket socket = mServerSocket.accept();
  176. Log.i("Client connection accepted");
  177. ClientConnection clientConnection =
  178. new ClientConnection(socket, mServer);
  179. mServer.postMessage(
  180. new Message("ClientConnectionCreated", clientConnection));
  181. }
  182. }
  183. }
  184. /**
  185. * This is the server socket that accepts editor connections.
  186. */
  187. static class EditorSocketAcceptor extends Thread
  188. {
  189. private int mPort;
  190. private Server mServer;
  191. private ServerSocket mServerSocket;
  192. public EditorSocketAcceptor(int port, Server server)
  193. {
  194. mPort = port;
  195. mServer = server;
  196. }
  197. public void run()
  198. {
  199. try
  200. {
  201. worker();
  202. }
  203. catch (IOException e)
  204. {
  205. e.printStackTrace();
  206. }
  207. }
  208. /**
  209. * Call close to terminate the thread.
  210. */
  211. public void close()
  212. {
  213. if (null != mServerSocket)
  214. {
  215. try
  216. {
  217. mServerSocket.close();
  218. }
  219. catch (IOException e)
  220. {
  221. e.printStackTrace();
  222. }
  223. }
  224. }
  225. public void worker() throws IOException
  226. {
  227. mServerSocket = new ServerSocket(mPort);
  228. while (true)
  229. {
  230. Log.i("Waiting for editor connection");
  231. Socket socket = mServerSocket.accept();
  232. Log.i("Editor connection accepted");
  233. EditorConnection editorConnection =
  234. new EditorConnection(socket, mServer);
  235. mServer.postMessage(
  236. new Message("EditorConnectionCreated", editorConnection));
  237. }
  238. }
  239. }
  240. static class ClientConnection extends MessageThread
  241. {
  242. private Socket mSocket;
  243. private Server mServer;
  244. private boolean mRunning;
  245. public ClientConnection(Socket socket, Server server)
  246. {
  247. mSocket = socket;
  248. mServer = server;
  249. mRunning = true;
  250. }
  251. public void run()
  252. {
  253. try
  254. {
  255. // Start communication.
  256. worker();
  257. }
  258. catch (IOException e)
  259. {
  260. e.printStackTrace();
  261. }
  262. finally
  263. {
  264. // Post connection closed message.
  265. mServer.postMessage(
  266. new Message("ClientConnectionClosed", this));
  267. }
  268. }
  269. public void worker() throws IOException
  270. {
  271. OutputStream out = mSocket.getOutputStream();
  272. InputStream in = mSocket.getInputStream();
  273. while (mRunning)
  274. {
  275. // Wait for message.
  276. Log.i("Waiting for message in client connection: " + this);
  277. Message message = waitForMessage();
  278. Log.i("ClientConnectionMessage: " + message.getMessage());
  279. // Send request to client.
  280. // First comes an int with length of string, then the string data as an byte string.
  281. String string = message.getObject().toString();
  282. byte[] byteString = string.getBytes("ISO-8859-1");
  283. int dataLength = byteString.length;
  284. // Assume little endian on client.
  285. int b1 = (dataLength) & 0xFF;
  286. int b2 = (dataLength >> 8) & 0xFF;
  287. int b3 = (dataLength >> 16) & 0xFF;
  288. int b4 = (dataLength >> 24) & 0xFF;
  289. Log.i(
  290. "dataLength: " + dataLength +
  291. " b1: " + b1 +
  292. " b2: " + b2 +
  293. " b3: " + b3 +
  294. " b4: " + b4);
  295. out.write(b1);
  296. out.write(b2);
  297. out.write(b3);
  298. out.write(b4);
  299. out.write(byteString);
  300. out.flush();
  301. Log.i("string: " + string);
  302. Log.i("byteString: " + byteString);
  303. // Wait for result.
  304. int bufSize = 2048;
  305. byte[] dataBuffer = new byte[bufSize];
  306. int numBytesRead = 0;
  307. // Read data.
  308. numBytesRead += in.read(dataBuffer); //, 0, bufSize - numRead);
  309. // Make sure that the data length bytes are read.
  310. while (numBytesRead < 4)
  311. {
  312. numBytesRead += in.read(
  313. dataBuffer,
  314. numBytesRead,
  315. bufSize - numBytesRead);
  316. }
  317. // Get length of data.
  318. int i1 = dataBuffer[0];
  319. int i2 = dataBuffer[1];
  320. int i3 = dataBuffer[2];
  321. int i4 = dataBuffer[3];
  322. dataLength =
  323. (i1) |
  324. (i2 << 8) |
  325. (i3 << 16) |
  326. (i4 << 24);
  327. Log.i(
  328. "dataLength: " + dataLength +
  329. " i1: " + i1 +
  330. " i2: " + i2 +
  331. " i3: " + i3 +
  332. " i4: " + i4);
  333. // Read remaining bytes.
  334. while (numBytesRead < 4 + dataLength)
  335. {
  336. numBytesRead += in.read(
  337. dataBuffer,
  338. numBytesRead,
  339. bufSize - numBytesRead);
  340. }
  341. String data = new String(dataBuffer, 4, dataLength, "ISO-8859-1");
  342. Log.i(
  343. "numRead: " + numBytesRead +
  344. " data: " + data);
  345. // Post result message to server.
  346. mServer.postMessage(new Message("MessageFromClient", data));
  347. }
  348. }
  349. }
  350. static class EditorConnection extends MessageThread
  351. {
  352. private Socket mSocket;
  353. private Server mServer;
  354. private boolean mRunning;
  355. public EditorConnection(Socket socket, Server server)
  356. {
  357. mSocket = socket;
  358. mServer = server;
  359. mRunning = true;
  360. }
  361. public void run()
  362. {
  363. try
  364. {
  365. // Start communication.
  366. startReader();
  367. startWriter();
  368. }
  369. catch (IOException e)
  370. {
  371. e.printStackTrace();
  372. }
  373. finally
  374. {
  375. // Post connection closed message.
  376. mServer.postMessage(
  377. new Message("EditorConnectionClosed", this));
  378. }
  379. }
  380. public void worker() throws IOException
  381. {
  382. OutputStream out = mSocket.getOutputStream();
  383. ObjectOutputStream objectOutStream = new ObjectOutputStream(out);
  384. InputStream in = mSocket.getInputStream();
  385. ObjectInputStream objectInStream = new ObjectInputStream(in);
  386. while (mRunning)
  387. {
  388. try
  389. {
  390. // Listen for commands from the editor. Commands
  391. // are sent as serialized Java objects of type Message.
  392. Log.i("Waiting for request in editor connection: " + this);
  393. Message request = (Message) objectInStream.readObject();
  394. Log.i("EditorConnectionMessage: " + request.getMessage());
  395. // Post request message to server.
  396. mServer.postMessage(request);
  397. // Wait for response from server. We should always get a
  398. // response message. Nevertheless, this is a nasty
  399. // synchronous assumption, would be better to make this
  400. // totally asynchronous and have readers and writers as
  401. // separate threads.
  402. Log.i("Waiting for response in editor connection: " + this);
  403. Message response = waitForMessage();
  404. Log.i("EditorConnectionMessage: " + response.getMessage());
  405. // Send response to editor.
  406. objectOutStream.writeObject(response);
  407. }
  408. catch (Exception ex)
  409. {
  410. ex.printStackTrace();
  411. }
  412. }
  413. }
  414. }
  415. }