]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.databoard/src/org/simantics/databoard/method/Server.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / method / Server.java
diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/method/Server.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/method/Server.java
new file mode 100644 (file)
index 0000000..53dbc92
--- /dev/null
@@ -0,0 +1,124 @@
+/*******************************************************************************\r
+ *  Copyright (c) 2010 Association for Decentralized Information Management in\r
+ *  Industry THTH ry.\r
+ *  All rights reserved. This program and the accompanying materials\r
+ *  are made available under the terms of the Eclipse Public License v1.0\r
+ *  which accompanies this distribution, and is available at\r
+ *  http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ *  Contributors:\r
+ *      VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.databoard.method;
+
+import java.io.IOException;\r
+import java.net.ServerSocket;\r
+import java.net.Socket;\r
+import java.util.List;\r
+import java.util.concurrent.CopyOnWriteArrayList;\r
+import java.util.logging.Level;\r
+import java.util.logging.Logger;\r
+\r
+import org.simantics.databoard.method.TcpConnection.ConnectionListener;\r
+
+/**
+ * Server opens a server socket and accepts incoming connections. 
+ * <p>
+ * Methods are invoked in read thread. Therefore method invocation blocks 
+ * the whole socket. 
+ * It is highly recommended that that MethodInterface implementation is 
+ * non-blocking.
+ *
+ * @author Toni Kalajainen <toni.kalajainen@vtt.fi>
+ */
+public class Server {
+       
+       static Logger LOGGER = Logger.getLogger(Server.class.getName());
+
+       ServerSocket socket;
+       Thread acceptThread;
+       MethodInterface handler;
+       List<TcpConnection> connections = new CopyOnWriteArrayList<TcpConnection>();
+       
+       /**
+        * Create new method interface server. 
+        * 
+        * @param port
+        * @param handler method handler of local methods or 
+        * @throws IOException
+        */
+       public Server(int port, MethodInterface handler) 
+       throws IOException
+       {
+               this.handler = handler;
+               
+               socket = new ServerSocket(port);
+               acceptThread = new Thread() {
+                       @Override
+                       public void run() {
+                               while(true) {
+                                       Socket s;
+                                       try {
+                                               s = socket.accept();
+                                       } catch (IOException e) {
+                                               return;
+                                       }
+                                       
+                                       try {
+                                               Handshake local = new Handshake();
+                                               local.methods = Server.this.handler.getInterface().getMethodDefinitions();
+                                               Handshake remote = TcpConnection.handshake(s, local);
+                                               final TcpConnection c = new TcpConnection(s, Server.this.handler, local, remote);                                               
+                                               c.addConnectionListener(new ConnectionListener() {
+                                                       @Override
+                                                       public void onClosed() {
+                                                               connections.remove(c);
+                                                       }
+                                                       @Override
+                                                       public void onError(Exception error) {
+                                                               connections.remove(c);
+                                                       }
+                                               });
+                                               
+                                               connections.add( c );                                           \r
+                                               if (c.getSocket().isClosed()) connections.remove(c);
+                                       } catch (IOException e) {
+                                               LOGGER.log(Level.FINER, "Connection Closed");
+                                               try {
+                                                       s.close();
+                                               } catch (IOException e1) {
+                                               }
+                                       }
+                               }                               
+                       }
+               };\r
+               acceptThread.setDaemon(true);
+               acceptThread.start();
+       }
+       
+       /**
+        * Stop listening for new connections and shutdown existing connections. 
+        */
+       public void close() {
+               try {
+                       socket.close();
+               } catch (IOException e) {
+               }
+               for (TcpConnection c : connections) {
+                       c.close();
+                       try {
+                               c.getSocket().close();
+                       } catch (IOException e) {
+                       }
+               }
+       }\r
+       \r
+       /** \r
+        * @return The port the server is listening.\r
+        */\r
+       public int getPort() {\r
+               return socket.getLocalPort(); \r
+       }
+       
+}
+