public void TransmissionReceived([FromBody]long transmissionId)
        {
            SecretUserId userId = UserIdExtractor.ReadSecretUserIdFromRequest(this.Request);
            using (TransmitContext context = new TransmitContext())
            {
                UserIdValidator validator = new UserIdValidator(context);
                validator.RequireSignedUserIdValid(userId);

                TransmissionsManager transmissionsManager = new TransmissionsManager(context);
                Transmission transmission = transmissionsManager.TransmissionReceived(userId.UserId, transmissionId);

                User sender = PushNotificationManager.GetUserById(transmission.Sender.UserId);
                if (sender != null)
                {
                    sender.SendPushNotification(new PushNotification(new PushMessage()
                    {
                        Method = "TransmissionReceivedConfirmed",
                        Data = new
                        {
                            Id = transmission.TransmissionId,
                            To = transmission.Receiver.UserId,
                            TimeReceived = transmission.TimeReceived
                        }
                    }));
                }
            }
        }
        public void SelectedPartnerChanged([FromBody]string selectedPartnerId)
        {
            SecretUserId userId = UserIdExtractor.ReadSecretUserIdFromRequest(this.Request);
            using (TransmitContext context = new TransmitContext())
            {
                UserIdValidator validator = new UserIdValidator(context);
                validator.RequireSignedUserIdValid(userId);

                UserManager userManager = new UserManager(context);
                userManager.SelectedPartnerChanged(userId.UserId, (string)selectedPartnerId);
            }
        }
        public void RemovePartner([FromBody]string partnerId)
        {
            SecretUserId userId = UserIdExtractor.ReadSecretUserIdFromRequest(this.Request);
            using (TransmitContext context = new TransmitContext())
            {
                UserIdValidator validator = new UserIdValidator(context);
                validator.RequireSignedUserIdValid(userId);

                UserManager userManager = new UserManager(context);
                userManager.RemovePartner(userId.UserId, partnerId);
            }
        }
        public PartnerList GetPartners()
        {
            SecretUserId userId = UserIdExtractor.ReadSecretUserIdFromRequest(this.Request);
            using (TransmitContext context = new TransmitContext())
            {
                UserIdValidator validator = new UserIdValidator(context);
                validator.RequireSignedUserIdValid(userId);

                UserManager userManager = new UserManager(context);
                return userManager.GetPartners(userId.UserId);
            }
        }
        public object SendTextTransmission(TextTransmissionModel textTransmission)
        {
            if (textTransmission == null) throw new ArgumentNullException("textTransmission");

            string partnerId = textTransmission.PartnerId;
            string text = textTransmission.Text;

            Transmission transmission;

            SecretUserId userId = UserIdExtractor.ReadSecretUserIdFromRequest(this.Request);
            using (TransmitContext context = new TransmitContext())
            {
                UserIdValidator validator = new UserIdValidator(context);
                validator.RequireSignedUserIdValid(userId);

                TransmissionsManager transmissionsManager = new TransmissionsManager(context);
                transmission = transmissionsManager.SendTextTransmission(userId.UserId, partnerId, text);
            }

            TextTransmissionData transmissionData = (TextTransmissionData)transmission.TransmissionData;

            User partner = PushNotificationManager.GetUserById(partnerId);
            if (partner != null)
            {
                partner.SendPushNotification(new PushNotification(new PushMessage()
                {
                    Method = "TextTransmissionReceived",
                    Data = new
                    {
                        Id = transmission.TransmissionId,
                        From = transmission.Sender.UserId,
                        TimeSend = transmission.TimeSend,
                        Text = text,
                        Format = Enum.GetName(typeof(TextDataFormat), transmissionData.DataFormat)
                    }
                }));

                return new
                {
                    Message = "ok",
                    ErrorCode = 0
                };
            }
            else
            {
                return new
                {
                    Message = "Partner not connected",
                    ErrorCode = 1
                };
            }
        }
        public void Alive()
        {
            SecretUserId userId = UserIdExtractor.ReadSecretUserIdFromRequest(this.Request);

            using (TransmitContext context = new TransmitContext())
            {
                UserIdValidator validator = new UserIdValidator(context);
                validator.RequireSignedUserIdValid(userId);

                User user = PushNotificationManager.GetUserById(userId.UserId);
                if (user != null)
                {
                    PushNotificationManager.UpdateUserTimeout(user.UserId);
                }
            }
        }
        public object AddPartner([FromBody]PartnerModel partner)
        {
            SecretUserId userId = UserIdExtractor.ReadSecretUserIdFromRequest(this.Request);

            Partner newPartner;
            using (TransmitContext context = new TransmitContext())
            {
                UserIdValidator validator = new UserIdValidator(context);
                validator.RequireSignedUserIdValid(userId);

                UserManager userManager = new UserManager(context);
                newPartner = userManager.AddPartner(userId.UserId, partner.Name, partner.Id);
            }

            return new
            {
                Name = newPartner.Name,
                Id = newPartner.PartnerUserId
            };
        }
        public SecretUserId CreateOrCheckUserId()
        {
            SecretUserId userId = UserIdExtractor.ReadSecretUserIdFromRequest(this.Request);

            using (TransmitContext context = new TransmitContext())
            {
                UserManager userManager = new UserManager(context);

                if (userId == null)
                {
                    return userManager.CreateNewUser();
                }
                else
                {
                    UserIdValidator validator = new UserIdValidator(context);
                    bool isValid = validator.IsSecredUserIdValid(userId);
                    return isValid ? userId : userManager.CreateNewUser();
                }
            }
        }
        public Task<PushNotification> GetPushNotification()
        {
            SecretUserId userId = UserIdExtractor.ReadSecretUserIdFromRequest(this.Request);

            User user;
            using (TransmitContext context = new TransmitContext())
            {
                UserIdValidator validator = new UserIdValidator(context);
                validator.RequireSignedUserIdValid(userId);

                user = PushNotificationManager.GetUserById(userId.UserId);

                if (user == null)
                {
                    UserManager userManager = new UserManager(context);
                    user = userManager.GetUserByUserIdOrThrow(userId.UserId);
                }
            }

            TaskCompletionSource<PushNotification> completionSource = new TaskCompletionSource<PushNotification>();

            #if DEBUG
            int id = _pushConnectionId++;
            Trace.TraceInformation("Notification {0} was started", id);
            #endif

            PushConnection pushConnection = new PushConnection(HttpContext.Current);
            pushConnection.SendPushNotificationEvent += notification =>
            {
            #if DEBUG
                Trace.TraceInformation("Sending notification to client:" + id);
            #endif
                completionSource.SetResult(notification);
            };
            user.PushConnections.Add(pushConnection);

            PushNotificationManager.UpdateOrAddUserToNotifiactionQuery(user);

            return completionSource.Task;
        }