mirror of
https://github.com/ChronosX88/KademliaDHT.git
synced 2024-11-23 10:42:21 +00:00
123 lines
3.4 KiB
Java
123 lines
3.4 KiB
Java
|
/**
|
||
|
* @author Joshua Kissoon
|
||
|
* @created 20140218
|
||
|
* @desc Operation that handles connecting to an existing Kademlia network using a bootstrap node
|
||
|
*/
|
||
|
package kademlia.operation;
|
||
|
|
||
|
import java.io.IOException;
|
||
|
import kademlia.core.Configuration;
|
||
|
import kademlia.core.KadServer;
|
||
|
import kademlia.exceptions.RoutingException;
|
||
|
import kademlia.message.AcknowledgeMessage;
|
||
|
import kademlia.message.ConnectMessage;
|
||
|
import kademlia.message.Message;
|
||
|
import kademlia.node.Node;
|
||
|
|
||
|
public class ConnectOperation implements Operation, Receiver
|
||
|
{
|
||
|
|
||
|
public static final int MAX_CONNECT_ATTEMPTS = 5; // Try 5 times to connect to a node
|
||
|
|
||
|
private final KadServer server;
|
||
|
private final Node localNode;
|
||
|
private final Node bootstrapNode;
|
||
|
|
||
|
private boolean error;
|
||
|
private int attempts;
|
||
|
|
||
|
/**
|
||
|
* @param server The message server used to send/receive messages
|
||
|
* @param local The local node
|
||
|
* @param bootstrap Node to use to bootstrap the local node onto the network
|
||
|
*/
|
||
|
public ConnectOperation(KadServer server, Node local, Node bootstrap)
|
||
|
{
|
||
|
this.server = server;
|
||
|
this.localNode = local;
|
||
|
this.bootstrapNode = bootstrap;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return null
|
||
|
*/
|
||
|
@Override
|
||
|
public synchronized Object execute()
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
/* Contact the bootstrap node */
|
||
|
this.error = true;
|
||
|
this.attempts = 0;
|
||
|
Message m = new ConnectMessage(this.localNode);
|
||
|
|
||
|
/* Send a connect message to the bootstrap node */
|
||
|
server.sendMessage(this.bootstrapNode, m, this);
|
||
|
|
||
|
/* Wait for a while */
|
||
|
wait(Configuration.OPERATION_TIMEOUT);
|
||
|
|
||
|
if (error)
|
||
|
{
|
||
|
/* Means the contact failed */
|
||
|
throw new RoutingException("Bootstrap node did not respond: " + bootstrapNode);
|
||
|
}
|
||
|
|
||
|
/* @todo Perform lookup for our own ID to get nodes close to us */
|
||
|
/* @todo Refresh buckets to get a good routing table */
|
||
|
return null;
|
||
|
|
||
|
}
|
||
|
catch (IOException | InterruptedException e)
|
||
|
{
|
||
|
e.printStackTrace();
|
||
|
}
|
||
|
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Receives an AcknowledgeMessage from the bootstrap node.
|
||
|
*
|
||
|
* @param comm
|
||
|
*/
|
||
|
@Override
|
||
|
public synchronized void receive(Message incoming, int comm)
|
||
|
{
|
||
|
/* The incoming message will be an acknowledgement message */
|
||
|
AcknowledgeMessage msg = (AcknowledgeMessage) incoming;
|
||
|
System.out.println("ConnectOperation now handling Acknowledgement Message: " + msg);
|
||
|
|
||
|
/* The bootstrap node has responded, insert it into our space */
|
||
|
this.localNode.getRoutingTable().insert(this.bootstrapNode);
|
||
|
|
||
|
/* We got a response, so the error is false */
|
||
|
error = false;
|
||
|
|
||
|
/* Wake up any waiting thread */
|
||
|
notify();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Resends a ConnectMessage to the boot strap node a maximum of MAX_ATTEMPTS
|
||
|
* times.
|
||
|
*
|
||
|
* @param comm
|
||
|
*
|
||
|
* @throws java.io.IOException
|
||
|
*/
|
||
|
@Override
|
||
|
public synchronized void timeout(int comm) throws IOException
|
||
|
{
|
||
|
if (++this.attempts < MAX_CONNECT_ATTEMPTS)
|
||
|
{
|
||
|
this.server.sendMessage(this.bootstrapNode, new ConnectMessage(this.localNode), this);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* We just exit, so notify all other threads that are possibly waiting */
|
||
|
notify();
|
||
|
}
|
||
|
}
|
||
|
}
|