private static void WriteCommand(dynamic dynamicElement, Command command)
        {
            switch (command.CommandType)
            {
            case CommandType.Login:
                LoginCommand loginCommand = (LoginCommand)command;
                dynamicElement.command.userInfo.name = loginCommand.UserInfo.Name;
                break;

            case CommandType.Ack:
                AckCommand ackCommand = (AckCommand)command;
                dynamicElement.command.messageId = ackCommand.MessageId;
                break;

            case CommandType.UserState:
                UserStateCommand userStateCommand = (UserStateCommand)command;
                dynamicElement.command.userInfo.name = userStateCommand.UserInfo.Name;
                dynamicElement.command.userState     = userStateCommand.UserState;
                break;

            case CommandType.TextMessage:
                TextMessageCommand textMessageCommand = (TextMessageCommand)command;
                dynamicElement.command.from.userInfo.name = textMessageCommand.From.Name;
                dynamicElement.command.to.userInfo.name   = textMessageCommand.To.Name;
                dynamicElement.command.textMessage        = textMessageCommand.Message;
                break;

            default:
                throw new InvalidOperationException("Unsupported command type: " + command.CommandType);
            }
        }
        /// <summary>
        /// Do handshake for client side.
        /// </summary>
        /// <param name="clientSocket"> Socket from client side to server side</param>
        /// <returns>null if handShake fail otherwise return instance of AProtocol</returns>
        public async Task <AProtocol> HandShakeClient(NetworkStream clientSocket)
        {
            HelloCommand hello = new HelloCommand(ClientConfig.SUPPORTED_PROTOCOLS);
            await hello.SendAsync(clientSocket);

            ACommand shouldBeOLLEH = GetCommand(await clientSocket.ReadLineAsync());

            if (shouldBeOLLEH is OllehCommand)
            {
                OllehCommand olleh    = (OllehCommand)shouldBeOLLEH;
                AProtocol    protocol = ClientConfig.PROTOCOL_FACTORY.GetProtocol(olleh.PROTOCOL);
                if (protocol != null)
                {
                    AckCommand ack = new AckCommand();
                    await ack.SendAsync(clientSocket);

                    return(protocol);
                }
                ErrorCommand error = new ErrorCommand($"Unsupported protocols '{olleh.PROTOCOL}'. Handshake failed.");
                await error.SendAsync(clientSocket);
            }
            else
            {
                printIfErrorElseSendMessage(shouldBeOLLEH, "Handshake error. Expected OllehCommand but receive " + shouldBeOLLEH.GetType().Name, clientSocket);
            }
            return(null);
        }
        public void Handle(AckCommand message)
        {
            CommandTracker tracker;

            _pendingCommands.TryGetValue(message.CommandId, out tracker);
            tracker?.Handle(message);
        }
        private void AckListener_OnMessageReceieved(object sender, AVIMMessageEventArgs e)
        {
            lock (mutex)
            {
                var ackCommand = new AckCommand().MessageId(e.Message.Id)
                                 .ConversationId(e.Message.ConversationId)
                                 .PeerId(this.ClientId);

                this.LinkedRealtime.AVIMCommandRunner.RunCommandAsync(ackCommand);
            }
        }
        internal async Task Ack(string convId,
                                string msgId)
        {
            AckCommand ack = new AckCommand {
                Cid = convId,
                Mid = msgId
            };
            GenericCommand command = NewCommand(CommandType.Ack);

            command.AckMessage = ack;
            await Connection.SendCommand(command);
        }
Exemple #6
0
        private void AckListener_OnMessageReceieved(object sender, AVIMMessageEventArgs e)
        {
            lock (mutex)
            {
                var ackCommand = new AckCommand().MessageId(e.Message.Id)
                                 .ConversationId(e.Message.ConversationId);

                // 在 v.2 协议下,只要在线收到消息,就默认是已读的,下次上线不会再把当前消息当做未读消息
                if (this.LinkedRealtime.CurrentConfiguration.OfflineMessageStrategy == AVRealtime.OfflineMessageStrategy.UnreadNotice)
                {
                    ackCommand = ackCommand.ReadAck();
                }

                this.RunCommandAsync(ackCommand);
            }
        }
Exemple #7
0
        public void Handle(AckCommand message)
        {
            Interlocked.Increment(ref _ackCount);
            var curState = Interlocked.Read(ref _state);

            if (curState != PendingAck || Interlocked.CompareExchange(ref _state, PendingResponse, curState) != curState)
            {
                if (Log.LogLevel >= LogLevel.Error)
                {
                    Log.Error(_command.GetType().Name + " Multiple Handlers Acked Command");
                }
                if (_tcs.TrySetException(new CommandOversubscribedException(" multiple handlers responded to the command", _command)))
                {
                    _cancelAction();
                }
                return;
            }
        }
        public Task MarkAsReadAsync(string conversationId = null, string messageId = null, AVIMConversation conversation = null, AVIMMessage message = null)
        {
            var msgId  = messageId != null ? messageId : message.Id;
            var convId = conversationId != null ? conversationId : conversation.ConversationId;

            if (convId == null && msgId == null)
            {
                throw new ArgumentNullException("发送已读回执的时候,必须指定 conversation id 或者 message id");
            }
            lock (mutex)
            {
                var ackCommand = new AckCommand()
                                 .ReadAck().MessageId(msgId)
                                 .ConversationId(convId)
                                 .PeerId(this.ClientId);

                return(this.LinkedRealtime.AVIMCommandRunner.RunCommandAsync(ackCommand));
            }
        }
Exemple #9
0
        public void Handle(AckCommand message)
        {
            Interlocked.Increment(ref _ackCount);
            var curState = Interlocked.Read(ref _state);

            if (curState != PendingAck || Interlocked.CompareExchange(ref _state, PendingResponse, curState) != curState)
            {
                if (Log.IsErrorEnabled)
                {
                    Log.Error(_command.GetType().Name + " Multiple Handlers Acked Command");
                }
                if (_tcs.TrySetException(new CommandOversubscribedException(" multiple handlers responded to the command", _command)))
                {
                    _cancelAction();
                }
                return;
            }
            Task.Delay(_responseTimeout, _canelTokenSource.Token).ContinueWith(_ => ResponseTimeout());
        }
Exemple #10
0
        public void ConvertAckCommandTest()
        {
            long version      = 1;
            long messageId    = 123123;
            long ackMessageId = 3242;

            AckCommand command = new AckCommand(ackMessageId);
            Message    message = new Message(version, messageId, command);

            //Converting to xml
            DynamicXmlMessageConverter converter = new DynamicXmlMessageConverter();
            XElement xml = converter.ConvertToXml(message);

            // And back again
            Message    message2 = converter.ConvertFromXml(xml);
            AckCommand command2 = (AckCommand)message2.Command;

            Assert.That(command2.MessageId, Is.EqualTo(command.MessageId));
        }
Exemple #11
0
        public void AckCommandTest()
        {
            string stringMessage =
                @"<message>
  <version>1</version>
  <messageId>123</messageId>
  <command type=""Ack"">
    <messageId>321</messageId>
  </command>
 </message>";

            XElement xml = XElement.Parse(stringMessage);
            DynamicXmlMessageConverter converter = new DynamicXmlMessageConverter();
            Message message = converter.ConvertFromXml(xml);

            // Checking command
            Command    command    = message.Command;
            AckCommand ackCommand = (AckCommand)command;

            Assert.That(ackCommand.CommandType, Is.EqualTo(CommandType.Ack));
            Assert.That(ackCommand.MessageId, Is.EqualTo(321));
        }
Exemple #12
0
        private void HandleLoginMessage(long incomingMessageId, LoginCommand command, IPEndPoint endPoint)
        {
            using (usersSync.UseWriteLock())
            {
                // Finding existing user or creating new one
                var currentUser = users.SingleOrDefault(ui => ui.UserInfo.Name == command.UserInfo.Name);
                if (currentUser == null)
                {
                    currentUser = new FullUserInfo(command.UserInfo);
                    users.Add(currentUser);
                }

                // Changing user state
                currentUser.OnConnect(endPoint);

                // Sending Ack message
                var ackCommand = new AckCommand(incomingMessageId);
                var message    = CreateMessage(ackCommand);
                SendMessage(endPoint, message);

                // Sending updated state
                SendUpdatedUserState(currentUser);
            }
        }
 void IHandle <AckCommand> .Handle(AckCommand ack)
 {
     Interlocked.Increment(ref _gotAck);
     SpinWait.SpinUntil(() => Interlocked.Read(ref _releaseAckHandler) == 1);
 }
Exemple #14
0
 public void Handle(AckCommand command)
 {
     Interlocked.Increment(ref GotAck);
 }
 public Task Ack() => AckCommand?.Invoke(false);
        internal async Task <LCIMMessage> Send(string convId,
                                               LCIMMessage message,
                                               LCIMMessageSendOptions options)
        {
            DirectCommand direct = new DirectCommand {
                FromPeerId = Client.Id,
                Cid        = convId,
            };

            if (message is LCIMTypedMessage typedMessage)
            {
                direct.Msg = JsonConvert.SerializeObject(typedMessage.Encode());
            }
            else if (message is LCIMBinaryMessage binaryMessage)
            {
                direct.BinaryMsg = ByteString.CopyFrom(binaryMessage.Data);
            }
            else
            {
                throw new ArgumentException("Message MUST be LCIMTypedMessage or LCIMBinaryMessage.");
            }
            // 暂态消息
            if (options.Transient)
            {
                direct.Transient = options.Transient;
            }
            // 消息接收回执
            if (options.Receipt)
            {
                direct.R = options.Receipt;
            }
            // 遗愿消息
            if (options.Will)
            {
                direct.Will = options.Will;
            }
            // 推送数据
            if (options.PushData != null)
            {
                direct.PushData = JsonConvert.SerializeObject(options.PushData);
            }
            // 提醒所有人
            if (message.MentionAll)
            {
                direct.MentionAll = message.MentionAll;
            }
            // 提醒用户列表
            if (message.MentionIdList != null &&
                message.MentionIdList.Count > 0)
            {
                direct.MentionPids.AddRange(message.MentionIdList);
            }
            GenericCommand command = NewCommand(CommandType.Direct);

            command.DirectMessage = direct;
            // 优先级
            if (command.Priority > 0)
            {
                command.Priority = (int)options.Priority;
            }
            GenericCommand response = await Connection.SendRequest(command);

            // 消息发送应答
            AckCommand ack = response.AckMessage;

            message.Id            = ack.Uid;
            message.SentTimestamp = ack.T;
            message.FromClientId  = Client.Id;
            return(message);
        }