Esempio n. 1
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="Client"></param>
 public RemoteActionServer(Server InServer)
 {
     Server = InServer;
     Server.OnRequestRemoteActionRecieved       += RequestRecieved;
     Server.OnCancelRemoteActionRecieved        += CancelRecieved;
     Server.OnSolicitAcceptRemoteActionRecieved += SolicitAcceptRecieved;
     Server.OnRemoteActionProgressRecieved      += (NetMessage_RemoteActionProgress Msg) =>
     {
         RemoteActionServerState Action = GetActionState(Msg.ActionId);
         if (Action != null)
         {
             if (Action.Completed != Msg.Completed ||
                 Action.Failed != Msg.Failed ||
                 Action.ResultMessage != Msg.ResultMessage ||
                 Action.Progress != Msg.Progress ||
                 Action.ProgressText != Msg.ProgressText)
             {
                 Action.Completed     = Msg.Completed;
                 Action.Failed        = Msg.Failed;
                 Action.ResultMessage = Msg.ResultMessage;
                 Action.Progress      = Msg.Progress;
                 Action.ProgressText  = Msg.ProgressText;
                 Action.Dirty         = true;
             }
             Action.LastUpdateRecieved = TimeUtils.Ticks;
         }
     };
 }
Esempio n. 2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="Msg"></param>
        private void RequestRecieved(NetConnection Client, NetMessage_RequestRemoteAction Msg)
        {
            RemoteActionServerState State = AllocateState(Msg.ActionId, Msg.Type);

            State.Settings     = Msg.Settings;
            State.ForClient    = Client;
            State.Progress     = 0.0f;
            State.ProgressText = "Waiting for available client ...";
            State.Dirty        = true;
        }
Esempio n. 3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="Client"></param>
        /// <param name="ActionId"></param>
        private void CancelRecieved(NetConnection Client, Guid ActionId)
        {
            RemoteActionServerState State = GetActionState(ActionId);

            if (State == null)
            {
                return;
            }

            State.Cancelled = true;
        }
Esempio n. 4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="Client"></param>
        /// <param name="ActionId"></param>
        private void SolicitAcceptRecieved(NetConnection Client, Guid ActionId)
        {
            RemoteActionServerState State = GetActionState(ActionId);

            if (State == null)
            {
                return;
            }

            State.SolicitationReplies.Add(Client);
        }
Esempio n. 5
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public RemoteActionServerState AllocateState(Guid Id, RemoteActionType Type)
        {
            RemoteActionServerState State = new RemoteActionServerState();

            State.Id   = Id;
            State.Type = Type;
            States.Add(State);

            Logger.Log(LogLevel.Info, LogCategory.Main, "Allocated new remote action '{0}' of type {1}.", State.Id.ToString(), State.Type.ToString());

            return(State);
        }
Esempio n. 6
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public void Poll()
        {
            for (int i = 0; i < States.Count; i++)
            {
                RemoteActionServerState State = States[i];

                // If this action has been allocated a client, wait for result.
                if (State.AllocatedClient != null)
                {
                    // Client has not updated us in quite a while :(
                    if (TimeUtils.Ticks - State.LastUpdateRecieved > RemoteActionServerState.LastUpdateTimeout)
                    {
                        Logger.Log(LogLevel.Info, LogCategory.Main, "Remote action '{0}' failed as no response has been heard from allocated client.", State.Id.ToString());

                        State.ResultMessage = "Remote client failed to send update in time.";
                        State.Completed     = true;
                        State.Failed        = true;
                        State.Dirty         = true;
                    }

                    // Client who was allocated this action has disconnected, so abort.
                    else if (!State.AllocatedClient.IsConnected)
                    {
                        Logger.Log(LogLevel.Info, LogCategory.Main, "Remote action '{0}' failed as allocated client disconnected.", State.Id.ToString());

                        State.ResultMessage = "Remote client unexpected disconnected.";
                        State.Completed     = true;
                        State.Failed        = true;
                        State.Dirty         = true;
                    }
                }

                // Otherwise send out a solicitation to perform action.
                else
                {
                    // Client who requested this action has disconnected, so abort.
                    if (!State.ForClient.IsConnected)
                    {
                        Logger.Log(LogLevel.Info, LogCategory.Main, "Remote action '{0}' failed as requesting client disconnected.", State.Id.ToString());

                        State.ResultMessage = "Requesting client unexpected disconnected.";
                        State.Completed     = true;
                        State.Failed        = true;
                        State.Dirty         = true;
                    }

                    // Client has cancelled this state.
                    else if (State.Cancelled)
                    {
                        Logger.Log(LogLevel.Info, LogCategory.Main, "Remote action '{0}' failed as client cancelled it.", State.Id.ToString());

                        State.ResultMessage = "Cancelled by user.";
                        State.Completed     = true;
                        State.Failed        = true;
                        State.Dirty         = true;

                        // Tell client allocated the job to cancel.
                        if (State.AllocatedClient != null && State.AllocatedClient.IsConnected)
                        {
                            NetMessage_CancelRemoteAction Msg = new NetMessage_CancelRemoteAction();
                            Msg.ActionId = State.Id;
                            State.AllocatedClient.Send(Msg);
                        }
                    }

                    // Send new solicitation.
                    else if (TimeUtils.Ticks - State.LastSolicitBroadcast > RemoteActionServerState.SolicitInterval)
                    {
                        Logger.Log(LogLevel.Info, LogCategory.Main, "Remote action '{0}' sending new solicitation request.", State.Id.ToString());

                        List <NetConnection> Clients = Server.ListenConnection.AllClients;
                        foreach (NetConnection ClientConnection in Clients)
                        {
                            if (ClientConnection != State.ForClient && ClientConnection.Metadata != null)
                            {
                                ServerConnectedClient ClientState = ClientConnection.Metadata as ServerConnectedClient;
                                if (ClientState.AllowRemoteActions)
                                {
                                    NetMessage_SolicitRemoteAction Msg = new NetMessage_SolicitRemoteAction();
                                    Msg.ActionId = State.Id;
                                    Msg.Type     = State.Type;
                                    Msg.Settings = State.Settings;
                                    ClientConnection.Send(Msg);
                                }
                            }
                        }

                        State.LastSolicitBroadcast = TimeUtils.Ticks;
                    }

                    // Nobody responded saying they can perform the action :|
                    else if (TimeUtils.Ticks - State.RecievedTime > RemoteActionServerState.SolicitTimeout)
                    {
                        Logger.Log(LogLevel.Info, LogCategory.Main, "Remote action '{0}' failed as nobody responded to solicitation.", State.Id.ToString());

                        State.ResultMessage = "No remote clients accepted request.";
                        State.Completed     = true;
                        State.Failed        = true;
                        State.Dirty         = true;
                    }

                    // We have a client who can do the job!
                    else if (State.SolicitationReplies.Count > 0 && TimeUtils.Ticks - State.LastSolicitBroadcast > RemoteActionServerState.MinSolicitWait)
                    {
                        Logger.Log(LogLevel.Info, LogCategory.Main, "Remote action '{0}' recieved solicitation reply and is starting.", State.Id.ToString());

                        State.AllocatedClient = State.SolicitationReplies[SolicitSelectionRandom.Next(0, State.SolicitationReplies.Count - 1)];
                        State.SolicitationReplies.Clear();
                        State.LastUpdateRecieved = TimeUtils.Ticks;

                        NetMessage_RequestRemoteAction Msg = new NetMessage_RequestRemoteAction();
                        Msg.ActionId = State.Id;
                        Msg.Type     = State.Type;
                        Msg.Settings = State.Settings;
                        State.AllocatedClient.Send(Msg);
                    }
                }

                // Send progress update to the client.
                if (TimeUtils.Ticks - State.LastUpdateSent > RemoteActionServerState.UpdateInterval || State.Dirty)
                {
                    if (State.ForClient.IsConnected)
                    {
                        if (State.Completed || TimeUtils.Ticks - State.LastUpdateSent > RemoteActionClientState.MinUpdateInterval)
                        {
                            NetMessage_RemoteActionProgress Msg = new NetMessage_RemoteActionProgress();
                            Msg.ActionId      = State.Id;
                            Msg.Completed     = State.Completed;
                            Msg.Failed        = State.Failed;
                            Msg.ResultMessage = State.ResultMessage;
                            Msg.Progress      = State.Progress;
                            Msg.ProgressText  = State.ProgressText;
                            State.ForClient.Send(Msg);

                            State.LastUpdateSent = TimeUtils.Ticks;
                        }
                    }

                    State.Dirty = false;

                    // If completed, clean up state.
                    if (State.Completed)
                    {
                        RemoveActionState(State.Id);
                    }
                }
            }
        }