示例#1
0
        private void Process()
        {
            List <Guid> dead = new List <Guid>();

            bool update = false;

            while (_alive)
            {
                try
                {
                    if (_listener.Pending())
                    {
                        ServerClient client = new ServerClient(_listener.AcceptTcpClient(), _timeout);
                        _feedback.WriteLine("Connecting: {0}", client);
                        _clients.TryAdd(client.SessionId, client);
                    }

                    foreach (KeyValuePair <Guid, ServerClient> item in _clients)
                    {
                        try
                        {
                            if (item.Value.State == ClientState.Dead)
                            {
                                dead.Add(item.Key);
                                continue;
                            }
                            else if (item.Value.State == ClientState.Ok && !_validator.ServerIsAllowed(item.Value.ServerId))
                            {
                                dead.Add(item.Key);
                                continue;
                            }

                            string value = item.Value.Tick();
                            if (value != null)
                            {
                                update = true;

                                if (item.Value.State == ClientState.HalfOpen)
                                {
                                    if (Guid.TryParse(value, out Guid serverid))
                                    {
                                        //Don't allow duplicates
                                        if (!_validator.ServerIsAllowed(serverid))
                                        {
                                            _feedback.WriteLine("Unauthorized: {0} -> {1}", item.Value.IP, serverid);
                                            item.Value.Kill("Unauthorized");
                                        }
                                        else if (_clients.Any(i => i.Value.ServerId == serverid && i.Value.State == ClientState.Ok))
                                        {
                                            _feedback.WriteLine("Already connected: {0} -> {1}", item.Value.IP, serverid);
                                            item.Value.Kill("Already connected");
                                        }
                                        else
                                        {
                                            _feedback.WriteLine("Upgrading: {0} -> {1}", item.Value.IP, serverid);
                                            item.Value.Upgrade(serverid);
                                            SendClientListToEveryone();
                                        }
                                    }
                                    else
                                    {
                                        _feedback.WriteLine("No proper serverid given: {0} -> {1}", item.Value.IP, value);
                                        item.Value.Kill("No valid serverid given");
                                    }
                                }
                                else if (!ProcessRequest(item.Value, value))
                                {
                                    item.Value.Kill("Request failed");
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            _feedback.Error(ex, false);
                            item.Value.Kill(ex.Message);
                        }
                    }

                    if (dead.Any())
                    {
                        bool fromOkState = false;

                        update = true;

                        dead.ForEach(i =>
                        {
                            if (_clients.TryRemove(i, out ServerClient dying))
                            {
                                _feedback.WriteLine("Disconnecting: {0} ({1})", dying, dying.DeathReason ?? "Disconnected");
                                fromOkState = fromOkState || dying.DeathState == ClientState.Ok;
                                dying.Dispose();
                            }
                        });
                        dead.Clear();

                        //Only send refresh of the clients if it was an established connection that died
                        if (fromOkState)
                        {
                            SendClientListToEveryone();
                        }
                    }
                }
                catch (Exception ex)
                {
                    _feedback.Error(ex, true);
                }

                if (update)
                {
                    _feedback.SetStatusLine($"{_clients.Count(i => i.Value.State == ClientState.Ok)} clients connected {_msgcnt} messages processed");

                    update = false;
                }

                try
                {
                    Thread.Sleep(1);
                }
                catch
                {
                    continue;
                }
            }
        }
示例#2
0
        public BaseTransmission SetWebRequest(Guid id, Guid target, string ip, string request, string body, Dictionary <string, string> headers)
        {
            ServerClient targetcli = GetClientFromClientId(target);

            if (targetcli == null)
            {
                return(null);
            }

            headers = headers ?? new Dictionary <string, string>();

            if (headers.ContainsKey("IP"))
            {
                headers.Remove("IP");
            }

            if (headers.ContainsKey("BODY"))
            {
                headers.Remove("BODY");
            }

            headers.Add("IP", ip);
            headers.Add("BODY", body ?? "");

            Dtos.WebRequest webrequest = new Dtos.WebRequest(new BaseTransmission
            {
                Action         = (int)ActionEnum.WebRequest,
                Data           = headers,
                SessionId      = targetcli.SessionId,
                Parameter      = request,
                TargetServerId = id
            }, id);

            lock (_webrequests)
            {
                _webrequests.Add(webrequest);
            }

            targetcli?.Send(Newtonsoft.Json.JsonConvert.SerializeObject(webrequest.Request));

            while (webrequest.Response == null)
            {
                Thread.Sleep(1);
                if (webrequest.Age > _timeout)
                {
                    lock (_webrequests)
                    {
                        _webrequests.Remove(webrequest);
                    }

                    throw new TimeoutException("Request timed out");
                }
            }

            lock (_webrequests)
            {
                _webrequests.Remove(webrequest);
            }

            return(webrequest.Response);
        }
示例#3
0
        private bool ProcessRequest(ServerClient from, string raw)
        {
            _msgcnt++;

            try
            {
                BaseTransmission request = Newtonsoft.Json.JsonConvert.DeserializeObject <BaseTransmission>(raw);

                if (request.SessionId != from.SessionId)
                {
                    return(false);
                }

                ActionEnum action = (ActionEnum)request.Action;

                if (action == ActionEnum.Ping || action == ActionEnum.Pong)
                {
                    return(true);
                }

                ServerClient target = request.TargetServerId == Guid.Empty ? null : GetClientFromClientId(request.TargetServerId);

                if (action == ActionEnum.SendMessageToTarget)
                {
                    _feedback.WriteLine("SendMessageToTarget: {0} -> {1}", from, raw);

                    target?.Send(Newtonsoft.Json.JsonConvert.SerializeObject(new BaseTransmission
                    {
                        Action         = (int)ActionEnum.SendMessageToTarget,
                        Data           = request.Data,
                        SessionId      = target.SessionId,
                        Parameter      = request.Parameter,
                        TargetServerId = from.ServerId
                    }));
                }
                else if (action == ActionEnum.WebRequest)
                {
                    _feedback.WriteLine("WebRequest: {0} -> {1}", from, raw);

                    Dtos.WebRequest webRequest;

                    lock (_webrequests)
                    {
                        webRequest = _webrequests
                                     .Where(i => i.Response == null && i.Request.TargetServerId == request.TargetServerId)
                                     .OrderByDescending(i => i.Age)
                                     .FirstOrDefault();
                    }

                    if (webRequest != null)
                    {
                        webRequest.SetResponse(request);
                    }
                }
                else if (action == ActionEnum.GetAllConnectedClients)
                {
                    _feedback.WriteLine("GetAllConnectedClients: {0} -> {1}", from, raw);

                    Dictionary <string, object> clients = new Dictionary <string, object>();

                    foreach (var item in _clients.Where(i => i.Value.State == ClientState.Ok).Select(i => i.Value))
                    {
                        clients.Add(item.ServerId.ToString(), _validator.GetClientName(item.ServerId));
                    }

                    from.Send(Newtonsoft.Json.JsonConvert.SerializeObject(new BaseTransmission
                    {
                        Action         = (int)ActionEnum.GetAllConnectedClients,
                        Data           = clients,
                        SessionId      = from.SessionId,
                        Parameter      = request.Parameter,
                        TargetServerId = Guid.Empty
                    }));
                }
                else
                {
                    _feedback.WriteLine("Unknown request: {0} from {1}", action, from);
                    return(false);
                }

                return(true);
            }
            catch (Exception ex)
            {
                _feedback.Error(ex, false);
                return(false);
            }
        }