Esempio n. 1
0
        /// <summary>
        /// Initiates a network query for a session
        /// </summary>
        /// <param name="TimeoutHandler">The Action that is called when the query times out</param>
        /// <returns>True if the network query was initiated. Otherwise, false</returns>
        protected bool QueryNetwork(System.Threading.WaitCallback TimeoutHandler)
        {
            ServiceSocket[] peers = service.LivePeers;
            if (!service.Settings.StandaloneMode && peers.Length > 0)
            {

                if (queryTimeout == null)
                {
                    queryTimeout = DateTime.UtcNow + new TimeSpan(0, 0, 0, 0, service.Settings.NetworkQueryTimeout);
                }

                //Log P2P Querying Network
                Diags.LogQueryingNetwork(Resource);

                //Create a new guid as the message id
                Guid msgID = Guid.NewGuid();

                //Add new query to Queries Initiated list (with one minute expiry)
                service.QueriesInitiated.Add(DateTime.UtcNow + new TimeSpan(0, 1, 0), msgID, null);

                //To get Origin Host: Get the LocalIP of the server IP + Port of peer listening socket
                //NOTE: Server IP must be valid within this routine because it is discovered in Server.NewLivePeer() and livePeers > 0
                string originEndPoint;
                {
                    string localhost;
                    int? localport;
                    ServerSettings.HostEndPoint.Parse(service.ServerIP, out localhost, out localport);
                    originEndPoint = new ServerSettings.HostEndPoint(localhost, service.Settings.PeerPort).ToString();
                }

                //Broadcast a GetTransferMessage which will call Process() when the session is returned
                //and processes TimeoutHandler delegate when the broadcast times out
                GetTransferMessage.Broadcast
                    (originEndPoint ,new List<ServiceSocket>(peers), service, Resource, msgID, service.Settings.MaxForwards, Guid.Empty, queryTimeout.Value,
                        delegate(string key) { Process(); }, //Found delegate simply reprocesses the request
                        delegate (object key) //Timeout delegate calls the time-out handler
                        {
                            Diags.LogNetworkQueryTimeout(Resource);
                            TimeoutHandler(key);
                        }
                    );

                return true;
            }
            else
            {
                return false;
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Called by the SessionDictionary.BeginExport method to complete processing the request, 
        /// if the requested session was found and read
        /// </summary>
        /// <param name="Session">The read session</param>
        /// <param name="StateObject">The state object passed from the SessionDictionary.BeginExport method</param>
        private void CompleteTransferRequest(ISessionObject Session, object StateObject)
        {
            ISessionResponseInfo response = Session.CreateResponseInfo();

            //Get the endpoint for the host to connect to
            string remoteHost;
            int? remotePort;
            ServerSettings.HostEndPoint.Parse(Host,out remoteHost,out remotePort);
            if(!remotePort.HasValue) remotePort = service.Settings.PeerPort;
            ServerSettings.HostEndPoint endPoint = new ServerSettings.HostEndPoint(remoteHost.Trim(),remotePort.Value);

            const int sentTransferExpiryTime = 2; // 2 seconds is sufficient for a broadcast to traverse half a reasonable network

            #region Callback Delegate declarations

            //SuccessAction
            Action<AsyncMessageTracker> successAction =
                delegate(AsyncMessageTracker asyncMsg)
                {
                    //Add this transfer to list of recently transferred sessions and have it expire in 15 seconds
                    service.SentTransfers.Add(DateTime.UtcNow + new TimeSpan(0, 0, sentTransferExpiryTime), Resource, null);

                    TransferSuccess(asyncMsg);
                    Diags.LogTransferSuccess(Resource);
                };

            //FailedAction
            Action<AsyncMessageTracker> failureAction =
                delegate(AsyncMessageTracker asyncMsg)
                {
                    TransferFailure(asyncMsg);
                    Diags.LogTransferFailed(Resource, string.Empty);

                };

            //AlreadyExistsAction
            Action<AsyncMessageTracker> alreadyExistsAction =
                delegate(AsyncMessageTracker asyncMsg)
                {
                    //Add this transfer to list of recently transferred sessions and have it expire in 15 seconds
                    service.SentTransfers.Add(DateTime.UtcNow + new TimeSpan(0, 0, sentTransferExpiryTime), Resource, null);

                    TransferSuccess(asyncMsg);
                    Diags.LogTransferFailed(Resource, "Resource already exists in remote peer -- deleted local copy");
                };

            //PeerShuttingDownAction
            Action<AsyncMessageTracker> peerShuttingDownAction =
                delegate(AsyncMessageTracker asyncMsg)
                {
                    TransferFailure(asyncMsg);
                    Diags.LogTransferFailed(Resource, "Peer is shutting down");
                };

            //TimeoutAction
            System.Threading.WaitCallback timeoutAction =
                delegate(object asyncMsg)
                {
                    //This anonymous method can be called directly from a background thread so make sure it's exception-safe
                    try
                    {
                        TransferFailure((AsyncMessageTracker)asyncMsg);
                        Diags.LogTransferFailed(Resource, "Timed out");
                    }
                    catch (Exception ex)
                    {
                        Diags.LogApplicationError( "TimeoutAction delegate error in CompleteTransferRequest", ex);
                    }
                };

            //FailedActionForExistingLink
            Action<AsyncMessageTracker> failureActionForExistingLink =
                delegate(AsyncMessageTracker asyncMsg)
                {
                    Diags.LogTransferFailed(Resource, "Existing link, trying again on new link");
                    //Try again by reconnecting
                    service.TransferSession(endPoint, Resource, response, Session.Data,
                        successAction, failureAction, alreadyExistsAction, peerShuttingDownAction, timeoutAction);

                };

            #endregion

            service.NewActiveExport(Resource); //create an entry in the exports list for this export

            //Look for standing link
            ServiceSocket linkSocket;
            if(service.TryGetLinkTo(endPoint, out linkSocket))
            {
                //There is a standing link to this peer so send transfer through it
                AsyncMessageTracker msg = new AsyncMessageTracker(AsyncMessageOperation.SetTransferOperation, Guid.NewGuid(), linkSocket);
                service.TransferSession(msg, Resource, response, Session.Data,
                    successAction, failureActionForExistingLink, alreadyExistsAction, peerShuttingDownAction, timeoutAction);
            }
            else
            {
                //Initiate a brand new connection
                service.TransferSession(endPoint, Resource, response, Session.Data,
                    successAction,failureAction,alreadyExistsAction,peerShuttingDownAction,timeoutAction);

            }
        }