changeset 136:81b558b38b9f

reconnection
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 08 Jun 2014 19:23:50 +0900
parents ada4d850a820
children 41f049cebcb5
files src/main/java/jp/ac/u_ryukyu/treevnc/TReeVNCCommand.java src/main/java/jp/ac/u_ryukyu/treevnc/client/TreeVncProtocol.java src/main/java/jp/ac/u_ryukyu/treevnc/server/AcceptClient.java src/main/java/jp/ac/u_ryukyu/treevnc/server/TreeVNCNode.java src/main/java/jp/ac/u_ryukyu/treevnc/server/VncProxyService.java
diffstat 5 files changed, 98 insertions(+), 177 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/TReeVNCCommand.java	Sat Jun 07 19:54:27 2014 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/TReeVNCCommand.java	Sun Jun 08 19:23:50 2014 +0900
@@ -120,7 +120,7 @@
      */
     private void handleLostParent(int port, String hostname) {
         try {
-            treeProtocol.lostParent(hostname, port);
+            viewer.fixLostParent(hostname,port);
         } catch (IOException e) {
             // log
         }
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/client/TreeVncProtocol.java	Sat Jun 07 19:54:27 2014 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/client/TreeVncProtocol.java	Sun Jun 08 19:23:50 2014 +0900
@@ -288,6 +288,7 @@
     public int getParentPort() {
         return echoPort;
     }
+    
 	/**
 	 * Start client with new parent (including reconnection) 
 	 * @param port
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/server/AcceptClient.java	Sat Jun 07 19:54:27 2014 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/AcceptClient.java	Sun Jun 08 19:23:50 2014 +0900
@@ -1,6 +1,5 @@
 package jp.ac.u_ryukyu.treevnc.server;
 
-import java.net.Socket;
 import java.net.UnknownHostException;
 import java.io.*;
 import java.net.*;
@@ -10,118 +9,50 @@
 import jp.ac.u_ryukyu.treevnc.client.TreeVncProtocol;
 
 public class AcceptClient {
-	private int nodeCounter = 0, parentnum = 0;
 	private LinkedList<TreeVNCNode> nodeList = new LinkedList<TreeVNCNode>();
-	private boolean addrRegistor = true;
 	boolean runflag = false;
 	private final int treebranch = 2;
-	private String myAddress;
-	private int leaderflag = 0;
-	private int sendleaderflag = 0;
-	private final int intv_time = 100;
-	private String defaultVNCport = "5999";
+	//  private final int intv_time = 100;    avoid too frequent reconnection
     private MyRfbProto rfb;
 
 	public AcceptClient(MyRfbProto rfb) {
 	    this.rfb = rfb;
+	    TreeVNCNode me = new TreeVNCNode( rfb.getMyAddress(), rfb.getAcceptPort());
+	    me.setTreeNum(0);
+        nodeList.add(me);
 	}
 	
-	public void transferParentAddrerss(BufferedReader is, PrintStream os) {
-		try {
-			while (true) {
-				String line = is.readLine();
-				String port = is.readLine();
-				myAddress = getMyAddress();
-				if ("1".equals(line) || "3".equals(line)) {
-					String treeNumber = is.readLine();
-					// reply to Parents lost node
-					replyLeaderNode(os, is, Integer.parseInt(port), Integer.parseInt(treeNumber));
-				} else if ("2".equals(line)) {
-					// reply to not Found Parents
-					TreeVNCNode newparent = replyNodeInformation(Integer.parseInt(port));
-					listupdate(port, newparent);
-					outputStream(os, newparent.getHostname(), String.valueOf(parentnum),
-							port, leaderflag==1?"1":"0");
-					os.close();
-					is.close();
-				} else if (line != null) {
-					// connection First time
-					if (checkAddress(line)) {
-						outputStream(os, myAddress, "0", "0", "0");
-						break;
-					} else {
-//						if (replyCreateTree(os, port, line)) {
-//							break;
-//						} else {
-//							break;
-//						}
-					}
-				}
-			}
-		} catch (IOException e) {
-			System.out.println(e);
-		} catch (InterruptedException e) {
-			e.printStackTrace();
-		}
-	}
-
-	private boolean checkAddress(String line) {
-		String test[] = line.split("\\.");
-		int a = Integer.parseInt(test[0]);
-		int b = Integer.parseInt(test[1]);
-		if ((192 == a && b == 168) || (172 == a && (b > 15 || b < 32))
-				|| 10 == a) {
-			return true;
-		} else {
-			return false;
-		}
-	}
+//
+//	private boolean checkAddress(String line) {
+//		String test[] = line.split("\\.");
+//		int a = Integer.parseInt(test[0]);
+//		int b = Integer.parseInt(test[1]);
+//		if ((192 == a && b == 168) || (172 == a && (b > 15 || b < 32))
+//				|| 10 == a) {
+//			return true;
+//		} else {
+//			return false;
+//		}
+//	}
 
 	/**
-	 * @param port
+	 * a parent is lost, remove from the list and move last one into here
+	 * @param nodeNum
 	 *            parent value
 	 */
-	private synchronized void listupdate(int port) {
-		nodeList.remove(port);
-		nodeList.add(port, nodeList.getLast());
-		nodeList.removeLast();
-	}
-
-	private synchronized void listupdate(String port, TreeVNCNode newparent) {
-		nodeList.remove(Integer.parseInt(port));
-		nodeList.add(Integer.parseInt(port), newparent);
-		nodeList.removeLast();
-	}
-
-	private void outputStream(PrintStream os, String request, String parentnum,
-			String treenum, String leaderflag) {
-		os.println(request);
-		os.println(parentnum);
-		os.println(treenum);
-		os.println(leaderflag);
+	private void moveLastNodeToLostNodePosition(int nodeNum) {
+		nodeList.remove(nodeNum);
+		TreeVNCNode node = nodeList.removeLast();
+		node.setTreeNum(nodeNum);
+		nodeList.add(nodeNum, node) ; 
 	}
 
 	private void checkParameter(int parent, int counter, int leaderflag2) {
-		System.out.println("number p =" + parentnum);
+		System.out.println("number p =" + parent);
 		System.out.println("number i =" + counter);
 		System.out.println("leaderflag=" + leaderflag2 + "\n");
 	}
 
-	private synchronized void addClientAdress(String line, LinkedList<TreeVNCNode> nodeList2) {
-		if (line != null) {
-			nodeList2.add(new TreeVNCNode(line));
-		}
-	}
-
-	private int decisionLeader(int counter, int treebranch) {
-		if ((counter - 1) % treebranch == 1) { // children in most young treenum
-												// have leaderflag 1 other 0
-			return 0;
-		} else {
-			return 1;
-		}
-	}
-
 	String getMyAddress() {
 		InetAddress addr = null;
 		try {
@@ -132,109 +63,82 @@
 		return addr.getHostAddress();
 	}
 
-	private TreeVNCNode replyNodeInformation(int port) {
-		parentnum = (port - 1) / treebranch;
-		sendleaderflag = decisionLeader(port, treebranch);
+	private TreeVNCNode getParentNode(int nodeNum) {
+		int parentnum = (nodeNum - 1) / treebranch;
         return  nodeList.get(parentnum);
 	}
+	
+	/**
+	 * A parent is lost, move last node which has no child to the position 
+	 * @param hostname
+	 * @param port
+	 */
+    public void fixLostParent(String hostname, int port) {
+        TreeVNCNode lostParentNode = lookup(nodeList,hostname,port);
+        if (lostParentNode == null ) return;   // some thing wrong
+        int treeNumber = lostParentNode.getTreeNum();
+        TreeVNCNode newparent = getParentNode(treeNumber);
+        moveLastNodeToLostNodePosition(treeNumber);
+        if(nodeList.size() > treeNumber +1)
+            lostNodeConnection(newparent);
+        // if lostParentNode is the last one, we don't need reconnection
+        // Thread.sleep(intv_time);
+    }
 
-	private synchronized void replyLeaderNode(PrintStream os, BufferedReader is, int port, int treeNumber) throws IOException,
-			InterruptedException {
-		String lastNode = nodeList.getLast().getHostname();
-		String checkSameHost = nodeList.get(treeNumber).getHostname();
-		if(lastNode != checkSameHost){
-			os.println(lastNode);
-		}
-		TreeVNCNode newparent = replyNodeInformation(port);
-		nodeCounter--;
-		reportLastNode(lastNode, newparent, port, parentnum, sendleaderflag);
-		listupdate(port);
-		if(lastNode != checkSameHost) {
-			os.println(this.defaultVNCport);
-			os.println(treeNumber);
-		}
-		leaderflag = decisionLeader(treeNumber, treebranch);
-		if(nodeList.size() > treeNumber +1)
-			lostNodeConnection(treeNumber, lastNode, this.defaultVNCport);
-		Thread.sleep(intv_time);
-		is.close();
-		os.close();
-	}
+    /**
+     * send reconnect to all children
+     * @param newparent
+     */
+    private void lostNodeConnection(TreeVNCNode newparent) {
+        for(int i=1; i < treebranch; i++ ) {
+            if (newparent.getTreeNum() + i <=nodeList.size() ) {
+                TreeVNCNode n = nodeList.get(newparent.getTreeNum()+i) ;
+                TreeVncProtocol vc = new TreeVncProtocol(n.getHostname(),n.getPort());
+                try {
+                    vc.connectTo(newparent.getHostname(), newparent.getPort(), isLeader(newparent));
+                } catch (IOException e) {
+                    // log
+                }
+            }
+        }
+    }
 
-	private void lostNodeConnection(int treeNum, String hostNode, String port)
-			throws UnknownHostException, IOException {
-		for (int i = 1; i < treebranch; i++) {
-			String host = nodeList.get(treeNum + i).getHostname();
-			if (host != hostNode) {
-				System.out.println("connection socket for-------------------- " + host);
-				Socket clients = new Socket(host, 10001);
-				clients.setReuseAddress(true);
-				DataOutputStream os = new DataOutputStream(clients.getOutputStream());
-				System.out.println("hostnode" + hostNode + "::port" + port);
-				os.writeBytes(hostNode + "\n");
-				os.writeBytes(port+"\n");
-				os.writeBytes(String.valueOf(treeNum + 1) + "\n");
-				os.close();
-				clients.close();
-			}
-		}
-	}
+    private int isLeader(TreeVNCNode n) {
+        return ( n.getTreeNum() % treebranch == 1) ? 1 : 0;
+    }
+
+    private TreeVNCNode lookup(LinkedList<TreeVNCNode> list, String hostname, int port) {
+	    for (TreeVNCNode r : list) {
+	        if (r.getHostname().equals(hostname) && r.getPort() == port )
+	                return r;
+	    }
+	    return null;
+    }
 
 	/**
-	 * Determin tree topology and send CONNECT_TO command
+	 * Determine tree topology and send CONNECT_TO command
 	 * @param hostname
 	 * @param port
 	 */
 	public void replyCreateTree(String hostname, int port) {
-	    if (addrRegistor == true) {
-	        nodeList.add(new TreeVNCNode(hostname,port));
-	        addrRegistor = false;
-	    }
-	    addClientAdress(hostname, nodeList);
-	    nodeCounter++;
+        TreeVNCNode node = new TreeVNCNode(hostname,port);
+        node.setTreeNum(nodeList.size());
+        nodeList.add(node);
 	    TreeVncProtocol treeProtocol = new TreeVncProtocol(hostname,port);
 	    try {
-	        if (nodeCounter >= treebranch + 1) {
-	            leaderflag = decisionLeader(nodeCounter, treebranch);
-	            parentnum = (nodeCounter - 1) / treebranch;
-	            String request = nodeList.get(parentnum).getHostname();
-	            int port1 = nodeList.get(parentnum).getPort();
-	            checkParameter(parentnum, nodeCounter, leaderflag);
-	            treeProtocol.connectTo(request,port1,leaderflag);
+	        if (nodeList.size() >= treebranch + 1) {
+	            TreeVNCNode parent = getParentNode(node.getTreeNum());
+	            checkParameter(parent.getTreeNum(), nodeList.size(), isLeader(node));
+	            treeProtocol.connectTo(parent.getHostname(),parent.getPort(),isLeader(node));
 	        } else {
 	            // connect to me
-	            treeProtocol.connectTo(rfb.getMyAddress(),rfb.getAcceptPort(),leaderflag);
+	            treeProtocol.connectTo(rfb.getMyAddress(),rfb.getAcceptPort(),isLeader(node));
 	        }
 	    } catch (IOException e) {
 	        // log
 	    }
 	}
 
-	void reportLastNode(String newchild, TreeVNCNode newparent, int newtreenum,
-			int newpnum, int newleaderflag) throws IOException {
-		try {
-			System.out.println(newchild + "connect");
-			Socket echoSocket = new Socket(newchild, 10001);
-			DataOutputStream os = new DataOutputStream(echoSocket.getOutputStream());
-			BufferedReader is = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
-			os.writeBytes(newparent .getHostname() + "\n");
-			os.writeBytes(this.defaultVNCport+"\n");
-			os.writeBytes(newpnum + "\n");
-			// os.writeBytes(newtreenum + "\n");
-			// os.writeBytes(newleaderflag + "\n");
-			// wait for last node connection
-			is.readLine();
-			is.close();
-			os.close();
-			echoSocket.close();
-		} catch (UnknownHostException e) {
-			System.err.println("Don't know about host: localhost");
-		} catch (IOException e) {
-			System.err
-					.println("Couldn't get I/O for the connection to: localhost");
-		}
-	}
-
 	public LinkedList<TreeVNCNode> getList() {
 		return nodeList;
 	}
@@ -246,4 +150,5 @@
 	public int getTreeBranch() {
 		return treebranch;
 	}
+
 }
\ No newline at end of file
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/server/TreeVNCNode.java	Sat Jun 07 19:54:27 2014 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/TreeVNCNode.java	Sun Jun 08 19:23:50 2014 +0900
@@ -7,7 +7,9 @@
 public class TreeVNCNode {
     String hostname;
     int port;
+    int treeNum;
     
+
     public TreeVNCNode(String myaddr) {
         hostname = myaddr;
         port = ConnectionParams.DEFAULT_VNC_ROOT;
@@ -18,6 +20,14 @@
         this.port = port;
     }
 
+    public int getTreeNum() {
+        return treeNum;
+    }
+
+    public void setTreeNum(int treeNum) {
+        this.treeNum = treeNum;
+    }
+    
     public String getHostname() {
         return hostname;
     }
@@ -26,4 +36,5 @@
         return port;
     }
 
+
 }
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/server/VncProxyService.java	Sat Jun 07 19:54:27 2014 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/VncProxyService.java	Sun Jun 08 19:23:50 2014 +0900
@@ -224,4 +224,8 @@
     public void replyCreateTree(String hostname, int port) {
         clients.replyCreateTree(hostname,port);
     }
+
+    public void fixLostParent(String hostname, int port) {
+        clients.fixLostParent(hostname,port);
+    }
 }