예제 #1
0
        private void HandleHello(IPEndPoint endpoint, Message message)
        {
            var client = GetClient(endpoint);

            if (client != null)
            {
                Debug($"Client with endpoint {endpoint.Address}:{endpoint.Port} already on list ({client.Nickname}).");
                return;
            }

            var nickname = message.GetTextContent();

            using (var database = new RozmawiatorDb())
            {
                var user = database.Users.FirstOrDefault(u => u.UserName == nickname);
                if (user == null)
                {
                    Debug($"Client {nickname} with endpoint {endpoint.Address}:{endpoint.Port} does not exist in database.");
                    return;
                }
            }

            var newClient = AddClient(endpoint, nickname);

            Send(newClient, Message.Hello(Configuration.Host.Name));

            Debug($"{nickname} connected ({endpoint.Address}:{endpoint.Port})");
            ClientConnected?.Invoke(newClient);
        }
예제 #2
0
        private void HandleCall(Client sender, Message message)
        {
            var calledNickname = message.GetTextContent();
            var calledUser     = GetClient(calledNickname);

            var callRequest = new Database.Entities.CallRequest
            {
                State = CallRequestState.NoResponse
            };

            using (var database = new RozmawiatorDb())
            {
                var callee =
                    database.Users.Select(u => new { u.Id, u.UserName }).FirstOrDefault(u => u.UserName == calledNickname);
                var caller =
                    database.Users.Select(u => new { u.Id, u.UserName })
                    .FirstOrDefault(u => u.UserName == sender.Nickname);

                callRequest.CalleeId = callee?.Id ?? Guid.Empty;
                callRequest.CallerId = caller?.Id ?? Guid.Empty;
            }

            Debug($"{sender.Nickname} is trying to call {calledNickname} ({sender.EndPoint.Address}:{sender.EndPoint.Port} -> ?)");

            if (calledUser == null)
            {
                Debug($"{sender.Nickname} was trying to call {calledNickname}, but {calledNickname} is offline.");
                Send(sender, Message.CallResponse(0, 0, Message.CallResponseType.TargetIsOffline));
                SaveCall(callRequest);
                return;
            }

            var conversation = GetInitiatedConversation(sender);

            if (conversation == null)
            {
                var currentConversation = GetConversation(sender);
                currentConversation?.Disconnect(sender);
                conversation = NewConversation(sender);
            }

            SaveCall(callRequest);
            conversation.AddRequest(calledUser);
            conversation.SendRequests();
        }
예제 #3
0
        private void HandleCallResponse(Client sender, Message message)
        {
            var callingClient = GetClient(message.Receiver);

            if (callingClient == null)
            {
                Debug($"{sender.Nickname} was trying to respond to call, but caller is offline.");
                Send(sender, Message.CallResponse(0, 0, Message.CallResponseType.TargetIsOffline));
                return;
            }

            var conversation = GetConversation(callingClient);

            if (conversation == null)
            {
                Debug($"{sender.Nickname} was trying to respond to {callingClient.Nickname}'s call, but the conversation no longer exists.");
                Send(sender, Message.CallResponse(0, 0, Message.CallResponseType.ExpiredCall));
                return;
            }

            var request = conversation.GetRequest(callingClient, sender);

            if (request == null)
            {
                Debug($"{sender.Nickname} was trying to respond to {callingClient.Nickname}'s call, but the request no longer exists.");
                Send(sender, Message.CallResponse(0, 0, Message.CallResponseType.ExpiredCall));
                return;
            }

            var response = request.ResolveRequest(message);



            switch (response)
            {
            case Message.CallResponseType.RequestDenied:
                Debug($"{sender.Nickname} declined {callingClient.Nickname}'s call.");
                break;

            case Message.CallResponseType.RequestAccepted:
                var currentConversation = GetConversation(sender);
                currentConversation?.Disconnect(sender);

                conversation.Join(sender);
                Debug($"{sender.Nickname} joined {callingClient.Nickname}'s conversation.");
                break;

            default:
                Debug($"Exception: Caller: {callingClient.Nickname}, Target: {sender.Nickname} - unexpected message {response}");
                break;
            }

            using (var database = new RozmawiatorDb())
            {
                var content       = message.GetTextContent();
                var lastTimestamp =
                    database.CallRequests.Where(
                        c => c.Callee.UserName == sender.Nickname).Max(c => c.Timestamp);

                /*
                 * var callRequest =
                 *  database.CallRequests.LastOrDefault(
                 *      c => c.Callee.UserName == sender.Nickname && c.Caller.UserName == content);
                 */
                var callRequest = database.CallRequests.FirstOrDefault(c => c.Timestamp == lastTimestamp);
                if (callRequest != null)
                {
                    callRequest.State = response == Message.CallResponseType.RequestAccepted
                        ? CallRequestState.RequestAccepted
                        : CallRequestState.RequestDenied;
                    database.SaveChanges();
                }
            }

            SendAsClient(sender, callingClient, Message.CallResponse(0, 0, response));
            conversation.RemoveRequests();
        }