/** * Creates a peer and starts to listen for incoming connections. * * @return The peer that can operate in the P2P network. * @throws IOException . */ public Peer start() throws IOException { boolean isBehindFirewallSet = false; if (behindFirewall == null) { behindFirewall = false; } else { isBehindFirewallSet = true; } boolean isTcpPortSet = false; if (tcpPort == -1) { tcpPort = Ports.DEFAULT_PORT; } else { isTcpPortSet = true; } boolean isUdpPortSet = false; if (udpPort == -1) { udpPort = Ports.DEFAULT_PORT; } else { isUdpPortSet = true; } if (channelServerConfiguration == null) { channelServerConfiguration = createDefaultChannelServerConfiguration(); } // post config if (isBehindFirewallSet) { channelServerConfiguration.behindFirewall(behindFirewall); } if (isTcpPortSet || isUdpPortSet) { channelServerConfiguration.ports(new Ports(tcpPort, udpPort, udpPort + 1)); } if (tcpPortForwarding == -1 && udpPortForwarding == -1) { channelServerConfiguration.portsForwarding(new Ports()); } else { channelServerConfiguration.portsForwarding( new Ports(tcpPortForwarding, udpPortForwarding, udpPortForwarding + 1)); } if (channelClientConfiguration == null) { channelClientConfiguration = createDefaultChannelClientConfiguration(); } if (keyPair == null) { keyPair = EMPTY_KEY_PAIR; } if (p2pID == -1) { p2pID = 1; } if (bindings == null) { bindings = new Bindings(); } else { channelServerConfiguration.bindings(bindings); channelClientConfiguration.bindings(bindings); } if (peerMap == null) { peerMap = new PeerMap(new PeerMapConfiguration(peerId)); } if (masterPeer == null && scheduledExecutorService == null) { scheduledExecutorService = Executors.newScheduledThreadPool(1); } if (sendBehavior == null) { sendBehavior = new DefaultSendBehavior(); } final PeerCreator peerCreator; if (masterPeer != null) { peerCreator = new PeerCreator(masterPeer.peerCreator(), peerId, keyPair); } else { peerCreator = new PeerCreator( p2pID, peerId, keyPair, channelServerConfiguration, channelClientConfiguration, scheduledExecutorService, sendBehavior); } final Peer peer = new Peer(p2pID, peerId, peerCreator); // add shutdown hook to master peer if (masterPeer != null) { masterPeer.addShutdownListener( new Shutdown() { @Override public BaseFuture shutdown() { return peer.shutdown(); } }); } PeerBean peerBean = peerCreator.peerBean(); peerBean.addPeerStatusListener(peerMap); ConnectionBean connectionBean = peerCreator.connectionBean(); peerBean.peerMap(peerMap); peerBean.keyPair(keyPair); if (bloomfilterFactory == null) { peerBean.bloomfilterFactory(new DefaultBloomfilterFactory()); } if (broadcastHandler == null) { broadcastHandler = new StructuredBroadcastHandler(); } broadcastHandler.init(peer); // set/enable RPC if (isEnableHandShakeRPC()) { PingRPC pingRPC = new PingRPC(peerBean, connectionBean); peer.pingRPC(pingRPC); } if (isEnableQuitRPC()) { QuitRPC quitRPC = new QuitRPC(peerBean, connectionBean); quitRPC.addPeerStatusListener(peerMap); peer.quitRPC(quitRPC); } if (isEnableNeighborRPC()) { NeighborRPC neighborRPC = new NeighborRPC(peerBean, connectionBean); peer.neighborRPC(neighborRPC); } if (isEnableDirectDataRPC()) { DirectDataRPC directDataRPC = new DirectDataRPC(peerBean, connectionBean); peer.directDataRPC(directDataRPC); } if (isEnableBroadcast()) { BroadcastRPC broadcastRPC = new BroadcastRPC(peerBean, connectionBean, broadcastHandler); peer.broadcastRPC(broadcastRPC); } if (isEnableRouting() && isEnableNeighborRPC()) { DistributedRouting routing = new DistributedRouting(peerBean, peer.neighborRPC()); peer.distributedRouting(routing); } if (maintenanceTask == null && isEnableMaintenance()) { maintenanceTask = new MaintenanceTask(); } if (maintenanceTask != null) { maintenanceTask.init(peer, connectionBean.timer()); maintenanceTask.addMaintainable(peerMap); } peerBean.maintenanceTask(maintenanceTask); // set the ping builder for the heart beat connectionBean .sender() .pingBuilderFactory( new PingBuilderFactory() { @Override public PingBuilder create() { return peer.ping(); } }); for (PeerInit peerInit : toInitialize) { peerInit.init(peer); } return peer; }