⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 relayclient.java

📁 JXTA&#8482 is a set of open, generalized peer-to-peer (P2P) protocols that allow any networked devi
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/* * Copyright (c) 2001-2007 Sun Microsystems, Inc.  All rights reserved. *   *  The Sun Project JXTA(TM) Software License *   *  Redistribution and use in source and binary forms, with or without  *  modification, are permitted provided that the following conditions are met: *   *  1. Redistributions of source code must retain the above copyright notice, *     this list of conditions and the following disclaimer. *   *  2. Redistributions in binary form must reproduce the above copyright notice,  *     this list of conditions and the following disclaimer in the documentation  *     and/or other materials provided with the distribution. *   *  3. The end-user documentation included with the redistribution, if any, must  *     include the following acknowledgment: "This product includes software  *     developed by Sun Microsystems, Inc. for JXTA(TM) technology."  *     Alternately, this acknowledgment may appear in the software itself, if  *     and wherever such third-party acknowledgments normally appear. *   *  4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must  *     not be used to endorse or promote products derived from this software  *     without prior written permission. For written permission, please contact  *     Project JXTA at http://www.jxta.org. *   *  5. Products derived from this software may not be called "JXTA", nor may  *     "JXTA" appear in their name, without prior written permission of Sun. *   *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND  *  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SUN  *  MICROSYSTEMS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *   *  JXTA is a registered trademark of Sun Microsystems, Inc. in the United  *  States and other countries. *   *  Please see the license information page at : *  <http://www.jxta.org/project/www/license.html> for instructions on use of  *  the license in source files. *   *  ==================================================================== *   *  This software consists of voluntary contributions made by many individuals  *  on behalf of Project JXTA. For more information on Project JXTA, please see  *  http://www.jxta.org. *   *  This license is based on the BSD license adopted by the Apache Foundation.  */package net.jxta.impl.endpoint.relay;import net.jxta.discovery.DiscoveryService;import net.jxta.document.Advertisement;import net.jxta.document.AdvertisementFactory;import net.jxta.document.MimeMediaType;import net.jxta.document.StructuredDocumentFactory;import net.jxta.document.StructuredDocumentUtils;import net.jxta.document.StructuredTextDocument;import net.jxta.document.XMLDocument;import net.jxta.document.XMLElement;import net.jxta.endpoint.EndpointAddress;import net.jxta.endpoint.EndpointService;import net.jxta.endpoint.Message;import net.jxta.endpoint.MessageElement;import net.jxta.endpoint.MessageReceiver;import net.jxta.endpoint.MessageSender;import net.jxta.endpoint.MessageTransport;import net.jxta.endpoint.Messenger;import net.jxta.id.ID;import net.jxta.id.IDFactory;import net.jxta.impl.protocol.RelayConfigAdv;import net.jxta.impl.util.SeedingManager;import net.jxta.impl.util.TimeUtils;import net.jxta.impl.util.URISeedingManager;import net.jxta.logging.Logging;import net.jxta.peer.PeerID;import net.jxta.peergroup.PeerGroup;import net.jxta.protocol.AccessPointAdvertisement;import net.jxta.protocol.PeerAdvertisement;import net.jxta.protocol.RdvAdvertisement;import net.jxta.protocol.RouteAdvertisement;import java.io.IOException;import java.net.URI;import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.Enumeration;import java.util.Hashtable;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Vector;import java.util.logging.Level;import java.util.logging.Logger;/** * RelayClient manages the relationship with the RelayServer(s) * */public class RelayClient implements MessageReceiver, Runnable {        /**     *  Logger     */    private final static transient Logger LOG = Logger.getLogger(RelayClient.class.getName());        private final static long DEFAULT_EXPIRATION = 20L * TimeUtils.AMINUTE;    private final PeerGroup group;    private final String serviceName;    private EndpointService endpoint;    private final EndpointAddress publicAddress;    private final String groupName;    private final String peerId;        private final int maxServers;    private final long leaseLengthToRequest;    private final long messengerPollInterval;        private Thread thread = null;        private volatile boolean closed = false;        /**     *  <ul>     *      <li>Values are {@link net.jxta.peergroup.PeerGroup}.</li>     *  </ul>     */    private final List activeRelayListeners = new ArrayList();        /**     *  <ul>     *      <li>Keys are {@link net.jxta.endpoint.EndpointAddress}.</li>     *      <li>Values are {@link net.jxta.protocol.RouteAdvertisement}.</li>     *  </ul>     */    private final Map<EndpointAddress, RouteAdvertisement> activeRelays = new Hashtable<EndpointAddress, RouteAdvertisement>();        /**     * Our source for relay servers.     */    private final SeedingManager seedingManager;        RelayServerConnection currentServer = null;        public RelayClient(PeerGroup group, String serviceName, RelayConfigAdv relayConfig) {        this.group = group;        this.groupName = group.getPeerGroupID().getUniqueValue().toString();                this.serviceName = serviceName;                maxServers = (-1 != relayConfig.getMaxRelays()) ? relayConfig.getMaxRelays() : RelayTransport.DEFAULT_MAX_SERVERS;        leaseLengthToRequest = (-1 != relayConfig.getClientLeaseDuration())                ? relayConfig.getClientLeaseDuration()                : RelayTransport.DEFAULT_LEASE;        messengerPollInterval = (-1 != relayConfig.getMessengerPollInterval())                ? relayConfig.getMessengerPollInterval()                : RelayTransport.DEFAULT_POLL_INTERVAL;                URISeedingManager uriSeedingManager = new URISeedingManager(relayConfig.getAclUri(), relayConfig.getUseOnlySeeds(), group, serviceName);                for (EndpointAddress aSeeder : Arrays.asList(relayConfig.getSeedRelays())) {            uriSeedingManager.addSeed(aSeeder.toURI());        }                for (URI aSeed : Arrays.asList(relayConfig.getSeedingURIs())) {            uriSeedingManager.addSeedingURI(aSeed);        }                this.seedingManager = uriSeedingManager;                // sanity check                peerId = group.getPeerID().getUniqueValue().toString();        publicAddress = new EndpointAddress(RelayTransport.protocolName, peerId, null, null);                if (Logging.SHOW_CONFIG && LOG.isLoggable(Level.CONFIG)) {            StringBuilder configInfo = new StringBuilder("Configuring Relay Client");                        configInfo.append("\n\tGroup Params :");            configInfo.append("\n\t\tGroup : ").append(group.getPeerGroupName());            configInfo.append("\n\t\tGroup ID : ").append(group.getPeerGroupID());            configInfo.append("\n\t\tPeer ID : ").append(group.getPeerID());            configInfo.append("\n\tConfiguration :");            configInfo.append("\n\t\tService Name : ").append(serviceName);            configInfo.append("\n\t\tPublic Address : ").append(publicAddress);            configInfo.append("\n\t\tMax Relay Servers : ").append(maxServers);            configInfo.append("\n\t\tMax Lease Length : ").append(leaseLengthToRequest).append("ms.");            configInfo.append("\n\t\tMessenger Poll Interval : ").append(messengerPollInterval).append("ms.");            LOG.config(configInfo.toString());        }    }        public synchronized boolean startClient() {        endpoint = group.getEndpointService();                if (endpoint.addMessageTransport(this) == null) {            if (Logging.SHOW_SEVERE && LOG.isLoggable(Level.SEVERE)) {                LOG.severe("Transport registration refused");            }            return false;        }                // start the client thread        thread = new Thread(group.getHomeThreadGroup(), this, "Relay Client Worker Thread for " + publicAddress);        thread.setDaemon(true);        thread.start();                if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {            LOG.info("Started client : " + publicAddress.toString());        }                return true;    }        public synchronized void stopClient() {        if (closed) {            return;        }                closed = true;                endpoint.removeMessageTransport(this);                // make sure the thread is not running        Thread tempThread = thread;                thread = null;        if (tempThread != null) {            tempThread.interrupt();        }                if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {            LOG.info("Stopped client : " + publicAddress.toString());        }            }        /**     * {@inheritDoc}     */    public Iterator<EndpointAddress> getPublicAddresses() {                return Collections.singletonList(publicAddress).iterator();    }        /**     * {@inheritDoc}     */    public String getProtocolName() {        return RelayTransport.protocolName;    }        /**     * {@inheritDoc}     */    public EndpointService getEndpointService() {        return endpoint;    }        /**     * {@inheritDoc}     */    public Object transportControl(Object operation, Object Value) {        return null;    }        /**     *  Logic for the relay client     *     *  <ol>     *      <li>Pick a relay server to try</li>     *      <li>try getting a messenger to relay server, if can not get messenger, start over</li>     *      <li>use the messenger to send a connect message</li>     *     <li> wait for a response, if there is no response or a disconnect response, start over</li>     *      <li>while still connected     *          <ol>     *          <li>renew the lease as needed and keep the messenger connected</li>     *          <ol></li>     *  </ol>     *     *  <p/>FIXME 20041102 bondolo The approach used here is really, really     *  stupid. The calls to <code>connectToRelay()</code> will not return if a     *  connection to a relay is achieved. This makes continued iteration over     * seeds after return incredibly silly. <code>connectToRelay()</code> only     *  returns when it can <b>NO LONGER CONNECT</b> to the relay. The only     *  hack I can think of to subvert this is to stop iteration of advs/seeds     *  if <code>connectToRelay()</code> takes a long time. bizarre.     */    public void run() {        if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {            LOG.info("Start relay client thread");        }                try {            long nextConnectAttemptAt = 0;                        RdvAdvertisement referral = null;            List<RouteAdvertisement> allSeeds = null;            long gotLastSeedsAt = 0;                        // run until the service is stopped            while (!closed) {                // Attempt to use any referral immediately.                if (null != referral) {                    RouteAdvertisement relayRoute = referral.getRouteAdv();                    relayRoute.setDestPeerID(referral.getPeerID());                                        referral = connectToRelay(new RelayServerConnection(this, relayRoute));                                        continue;                }                                // Sleep until it is time for the next connection attempt.                long untilNextConnectAttempt = TimeUtils.toRelativeTimeMillis(nextConnectAttemptAt);                                if (untilNextConnectAttempt > 0) {                    try {                        Thread.sleep(untilNextConnectAttempt);                    } catch (InterruptedException e) {                        // ignore interrupted exception                        if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {                            LOG.log(Level.FINE, "Thread Interrupted ", e);                        }                                                continue;                    }                }                                // Don't allow next connection attempt to start any sooner than this.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -