Example #1
0
 public static UnsubAckPacket InResponseTo(UnsubscribePacket unsubscribePacket)
 {
     return new UnsubAckPacket
     {
         PacketId = unsubscribePacket.PacketId
     };
 }
Example #2
0
        /// <summary>
        /// 取消订阅
        /// </summary>
        /// <param name="topics">主题</param>
        public Task <UnsubscribeAckMessage> UnsubscribeAsync(params string[] topics)
        {
            var packet = new UnsubscribePacket();

            packet.AddRange(topics);

            return(SendAndReceiveAsync <UnsubscribeAckMessage>(packet, _cancellationTokenSource.Token));;
        }
Example #3
0
 private void Unsubscribe(UnsubscribePacket packet)
 {
     if (packet.PacketId == 0)
     {
         packet.PacketId = this.GetNextPacketId();
     }
     Send(packet);
 }
 public void Process(UnsubscribePacket packet, NetPeer peer)
 {
     if (ChannelManager.Global.Channels.ContainsKey(packet.Channel))
     {
         Logger.Log(peer.EndPoint + " unsubscribed from " + packet.Channel);
         var channel = ChannelManager.Global.Channels[packet.Channel];
         channel.Subscibers.Remove(peer);
     }
 }
Example #5
0
        bool TryDecodePacket(IChannelHandlerContext context, IByteBuffer buffer, out Packet packet)
        {
            if (!buffer.IsReadable(2))
            {
                packet = null;
                return(false);
            }

            byte signature = buffer.ReadByte();

            if (!TryDecodeRemainingLength(buffer, out int remainingLength) || !buffer.IsReadable(remainingLength))
            {
                packet = null;
                return(false);
            }

            var fixedHeader = new FixedHeader(signature, remainingLength);

            switch (fixedHeader.PacketType)
            {
            case PacketType.CONNECT: packet = new ConnectPacket(); break;

            case PacketType.CONNACK: packet = new ConnAckPacket(); break;

            case PacketType.DISCONNECT: packet = new DisconnectPacket(); break;

            case PacketType.PINGREQ: packet = new PingReqPacket(); break;

            case PacketType.PINGRESP: packet = new PingRespPacket(); break;

            case PacketType.PUBACK: packet = new PubAckPacket(); break;

            case PacketType.PUBCOMP: packet = new PubCompPacket(); break;

            case PacketType.PUBLISH: packet = new PublishPacket(); break;

            case PacketType.PUBREC: packet = new PubRecPacket(); break;

            case PacketType.PUBREL: packet = new PubRelPacket(); break;

            case PacketType.SUBSCRIBE: packet = new SubscribePacket(); break;

            case PacketType.SUBACK: packet = new SubAckPacket(); break;

            case PacketType.UNSUBSCRIBE: packet = new UnsubscribePacket(); break;

            case PacketType.UNSUBACK: packet = new UnsubscribePacket(); break;

            default:
                throw new DecoderException("Unsupported Message Type");
            }
            packet.FixedHeader = fixedHeader;
            packet.Decode(buffer);

            return(true);
        }
Example #6
0
        public void TestUnsubscribeMessage(int packetId, string[] topicFilters)
        {
            var packet = new UnsubscribePacket(packetId, topicFilters);

            UnsubscribePacket recoded = this.RecodePacket(packet, true, true);

            this.contextMock.Verify(x => x.FireChannelRead(It.IsAny <UnsubscribePacket>()), Times.Once);
            Assert.Equal(packet.TopicFilters, recoded.TopicFilters);
            Assert.Equal(packet.PacketId, recoded.PacketId);
        }
        public async Task ShouldNotAssumeEventOrdering_UnsubscribeContinuesBeforeUnsubAckReceived()
        {
            var request = new UnsubscribePacket(0, "myTopic");
            Func <PacketWithId, UnsubAckPacket> ackFactory =
                (packet) => new UnsubAckPacket()
            {
                PacketId = packet.PacketId
            };

            await SendRequestAndAcknowledgementsInSpecificOrder(request, ackFactory, false).ConfigureAwait(false);
        }
        public static UnsubAckPacket RemoveSubscriptions(ISessionState session, UnsubscribePacket packet)
        {
            foreach (string topicToRemove in packet.TopicFilters)
            {
                session.RemoveSubscription(topicToRemove);
            }
            var ack = new UnsubAckPacket
            {
                PacketId = packet.PacketId
            };

            return(ack);
        }
        async Task UnSubscribeAsync(IChannelHandlerContext context, UnsubscribePacket packetPassed)
        {
            Contract.Assert(packetPassed != null);

            int packetId = Util.GetNextPacketId();

            packetPassed.PacketId = packetId;

            this.unsubscribeCompletions[packetId] = new TaskCompletionSource();

            await Util.WriteMessageAsync(context, packetPassed, ShutdownOnWriteErrorHandler);

            await this.unsubscribeCompletions[packetId].Task;
        }
Example #10
0
 private async Task checkSubscriptionsAsync(string topic, TaskCompletionSource <object> promise)
 {
     if (!topicSubscriptions.ContainsKey(topic) && subscribedTopics.Contains(topic))
     {
         UnsubscribePacket  packet             = new UnsubscribePacket(PacketIdProvider.NewPacketId(), topic);
         PendingUnsubscribe pendingUnsubscribe = new PendingUnsubscribe(promise, topic, packet);
         pendingUnsubscribes.TryAdd(packet.PacketId, pendingUnsubscribe);
         pendingUnsubscribe.Retransmit(eventLoopGroup.GetNext(), sendAndFlushAsync);
         await sendAndFlushAsync(packet);
     }
     else
     {
         promise.SetResult(null);
     }
 }
Example #11
0
        public Task <IMqttResult> UnSubscribe(MqttClientSession clientSession, UnsubscribePacket unSubscribePacket)
        {
            if (CLIENT_DIC.TryGetValue(clientSession.ClientId, out List <MqttSubscription> subList))
            {
                foreach (string topicFilter in unSubscribePacket.TopicFilters)
                {
                    subList.RemoveAll(x => x.Topic == topicFilter);

                    if (TOPIC_DIC.TryGetValue(topicFilter, out List <string> clientIds))
                    {
                        clientIds.Remove(clientSession.ClientId);
                    }
                }
            }

            return(Task.FromResult <IMqttResult>(SubscribeResult.SUCCESS));
        }
Example #12
0
        static void EncodeUnsubscribeMessage(IByteBufferAllocator bufferAllocator, UnsubscribePacket packet, List <object> output)
        {
            const int VariableHeaderSize = 2;
            int       payloadBufferSize  = 0;

            ThreadLocalObjectList encodedTopicFilters = ThreadLocalObjectList.NewInstance();

            IByteBuffer buf = null;

            try
            {
                foreach (string topic in packet.TopicFilters)
                {
                    byte[] topicFilterBytes = EncodeStringInUtf8(topic);
                    payloadBufferSize += StringSizeLength + topicFilterBytes.Length; // length, value
                    encodedTopicFilters.Add(topicFilterBytes);
                }

                int variablePartSize      = VariableHeaderSize + payloadBufferSize;
                int fixedHeaderBufferSize = 1 + MaxVariableLength;

                buf = bufferAllocator.Buffer(fixedHeaderBufferSize + variablePartSize);
                buf.WriteByte(CalculateFirstByteOfFixedHeader(packet));
                WriteVariableLengthInt(buf, variablePartSize);

                // Variable Header
                buf.WriteShort(packet.PacketId); // todo: review: validate?

                // Payload
                for (int i = 0; i < encodedTopicFilters.Count; i++)
                {
                    var topicFilterBytes = (byte[])encodedTopicFilters[i];
                    buf.WriteShort(topicFilterBytes.Length);
                    buf.WriteBytes(topicFilterBytes, 0, topicFilterBytes.Length);
                }

                output.Add(buf);
                buf = null;
            }
            finally
            {
                buf?.SafeRelease();
                encodedTopicFilters.Return();
            }
        }
        /// <summary>
        /// Unsubscribes the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="packet">The packet.</param>
        public async Task Unsubscribe(IChannelHandlerContext context, UnsubscribePacket packet)
        {
            var topics   = packet.TopicFilters.ToArray();
            var deviceId = await _channelService.GetDeviceId(context.Channel);

            var message = TransportMessage.CreateInvokeMessage(new RemoteInvokeMessage
            {
                ServiceId = "Unsubscribe", Parameters = new Dictionary <string, object> {
                    { "packet", packet }
                }
            });

            WirteDiagnosticBefore(message, context.Channel.RemoteAddress.ToString(), deviceId, packet.PacketType);
            await _channelService.UnSubscribe(deviceId, topics);

            await UnsubAck(context, UnsubAckPacket.InResponseTo(packet));

            WirteDiagnosticAfter(message);
        }
Example #14
0
        Packet DecodePacketInternal(IByteBuffer buffer, byte packetSignature, ref int remainingLength)
        {
            Packet packet;
            var    fixedHeader = new FixedHeader(packetSignature, remainingLength);

            switch (fixedHeader.PacketType)
            {
            case PacketType.CONNECT: packet = new ConnectPacket(); break;

            case PacketType.CONNACK: packet = new ConnAckPacket(); break;

            case PacketType.DISCONNECT: packet = new DisconnectPacket(); break;

            case PacketType.PINGREQ: packet = new PingReqPacket(); break;

            case PacketType.PINGRESP: packet = new PingRespPacket(); break;

            case PacketType.PUBACK: packet = new PubAckPacket(); break;

            case PacketType.PUBCOMP: packet = new PubCompPacket(); break;

            case PacketType.PUBLISH: packet = new PublishPacket(); break;

            case PacketType.PUBREC: packet = new PubRecPacket(); break;

            case PacketType.PUBREL: packet = new PubRelPacket(); break;

            case PacketType.SUBSCRIBE: packet = new SubscribePacket(); break;

            case PacketType.SUBACK: packet = new SubAckPacket(); break;

            case PacketType.UNSUBSCRIBE: packet = new UnsubscribePacket(); break;

            case PacketType.UNSUBACK: packet = new UnsubscribePacket(); break;

            default:
                throw new DecoderException("Unsupported Message Type");
            }
            packet.FixedHeader = fixedHeader;
            packet.Decode(buffer);
            remainingLength = packet.RemaingLength;
            return(packet);
        }
Example #15
0
        static void DecodeUnsubscribePayload(IByteBuffer buffer, UnsubscribePacket packet, ref int remainingLength)
        {
            //var unsubscribeTopics = new List<string>();
            //while (remainingLength > 0)
            //{
            //    string topicFilter = DecodeString(buffer, ref remainingLength);
            //    ValidateTopicFilter(topicFilter);
            //    unsubscribeTopics.Add(topicFilter);
            //}

            //if (unsubscribeTopics.Count == 0)
            //{
            //    throw new DecoderException("[MQTT-3.10.3-2]");
            //}

            //packet.TopicFilters = unsubscribeTopics;

            //remainingLength = 0;
        }
Example #16
0
        static void DecodeUnsubscribePayload(IByteBuffer buffer, UnsubscribePacket packet, ref int remainingLength)
        {
            var unsubscribeTopics = new List <string>();

            while (remainingLength > 0)
            {
                string topicFilter = DecodeString(buffer, ref remainingLength);
                ValidateTopicFilter(topicFilter);
                unsubscribeTopics.Add(topicFilter);
            }

            if (0u >= (uint)unsubscribeTopics.Count)
            {
                ThrowHelper.ThrowDecoderException_MQTT_3103_2();
            }

            packet.TopicFilters = unsubscribeTopics;

            remainingLength = 0;
        }
Example #17
0
        static void DecodeUnsubscribePayload(DataReader reader, UnsubscribePacket packet, ref uint remainingLength)
        {
            var unsubscribeTopics = new List <string>();

            while (remainingLength > 0)
            {
                string topicFilter = DecodeString(reader, ref remainingLength);
                ValidateTopicFilter(topicFilter);
                unsubscribeTopics.Add(topicFilter);
            }

            if (unsubscribeTopics.Count == 0)
            {
                throw new DecoderException("[MQTT-3.10.3-2]");
            }

            packet.TopicFilters = unsubscribeTopics;

            remainingLength = 0;
        }
        public static UnsubAckPacket RemoveSubscriptions(ISessionState session, UnsubscribePacket packet)
        {
            List <Subscription> subscriptions = session.Subscriptions;

            foreach (string topicToRemove in packet.TopicFilters)
            {
                for (int i = subscriptions.Count - 1; i >= 0; i--)
                {
                    if (subscriptions[i].TopicFilter.Equals(topicToRemove, StringComparison.Ordinal))
                    {
                        subscriptions.RemoveAt(i);
                        break;
                    }
                }
            }
            var ack = new UnsubAckPacket
            {
                PacketId = packet.PacketId
            };

            return(ack);
        }
Example #19
0
        async Task UnSubscribeAsync(IChannelHandlerContext context, UnsubscribePacket packetPassed)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, context.Name, packetPassed, nameof(UnSubscribeAsync));
            }

            Contract.Assert(packetPassed != null);

            int packetId = Util.GetNextPacketId();

            packetPassed.PacketId = packetId;

            this.unsubscribeCompletions[packetId] = new TaskCompletionSource();

            await Util.WriteMessageAsync(context, packetPassed, ShutdownOnWriteErrorHandler).ConfigureAwait(true);

            await this.unsubscribeCompletions[packetId].Task.ConfigureAwait(true);

            if (Logging.IsEnabled)
            {
                Logging.Exit(this, context.Name, packetPassed, nameof(UnSubscribeAsync));
            }
        }
 public abstract void Unsubscribe(IChannelHandlerContext context, UnsubscribePacket packet);
Example #21
0
        Packet DecodePacketInternal(IByteBuffer buffer, int packetSignature, ref int remainingLength, IChannelHandlerContext context)
        {
            if (Signatures.IsPublish(packetSignature))
            {
                var qualityOfService = (QualityOfService)((packetSignature >> 1) & 0x3); // take bits #1 and #2 ONLY and convert them into QoS value
                if (qualityOfService == QualityOfService.Reserved)
                {
                    ThrowHelper.ThrowDecoderException_UnexpectedQoSValueForPublish(qualityOfService);
                }

                bool duplicate = (packetSignature & 0x8) == 0x8; // test bit#3
                bool retain    = (packetSignature & 0x1) != 0;   // test bit#0
                var  packet    = new PublishPacket(qualityOfService, duplicate, retain);
                DecodePublishPacket(buffer, packet, ref remainingLength);
                return(packet);
            }

            switch (packetSignature) // strict match checks for valid message type + correct values in flags part
            {
            case Signatures.PubAck:
                var pubAckPacket = new PubAckPacket();
                DecodePacketIdVariableHeader(buffer, pubAckPacket, ref remainingLength);
                return(pubAckPacket);

            case Signatures.PubRec:
                var pubRecPacket = new PubRecPacket();
                DecodePacketIdVariableHeader(buffer, pubRecPacket, ref remainingLength);
                return(pubRecPacket);

            case Signatures.PubRel:
                var pubRelPacket = new PubRelPacket();
                DecodePacketIdVariableHeader(buffer, pubRelPacket, ref remainingLength);
                return(pubRelPacket);

            case Signatures.PubComp:
                var pubCompPacket = new PubCompPacket();
                DecodePacketIdVariableHeader(buffer, pubCompPacket, ref remainingLength);
                return(pubCompPacket);

            case Signatures.PingReq:
                if (!_isServer)
                {
                    ValidateServerPacketExpected(packetSignature);
                }
                return(PingReqPacket.Instance);

            case Signatures.Subscribe:
                if (!_isServer)
                {
                    ValidateServerPacketExpected(packetSignature);
                }
                var subscribePacket = new SubscribePacket();
                DecodePacketIdVariableHeader(buffer, subscribePacket, ref remainingLength);
                DecodeSubscribePayload(buffer, subscribePacket, ref remainingLength);
                return(subscribePacket);

            case Signatures.Unsubscribe:
                if (!_isServer)
                {
                    ValidateServerPacketExpected(packetSignature);
                }
                var unsubscribePacket = new UnsubscribePacket();
                DecodePacketIdVariableHeader(buffer, unsubscribePacket, ref remainingLength);
                DecodeUnsubscribePayload(buffer, unsubscribePacket, ref remainingLength);
                return(unsubscribePacket);

            case Signatures.Connect:
                if (!_isServer)
                {
                    ValidateServerPacketExpected(packetSignature);
                }
                var connectPacket = new ConnectPacket();
                DecodeConnectPacket(buffer, connectPacket, ref remainingLength, context);
                return(connectPacket);

            case Signatures.Disconnect:
                if (!_isServer)
                {
                    ValidateServerPacketExpected(packetSignature);
                }
                return(DisconnectPacket.Instance);

            case Signatures.ConnAck:
                if (_isServer)
                {
                    ValidateClientPacketExpected(packetSignature);
                }
                var connAckPacket = new ConnAckPacket();
                DecodeConnAckPacket(buffer, connAckPacket, ref remainingLength);
                return(connAckPacket);

            case Signatures.SubAck:
                if (_isServer)
                {
                    ValidateClientPacketExpected(packetSignature);
                }
                var subAckPacket = new SubAckPacket();
                DecodePacketIdVariableHeader(buffer, subAckPacket, ref remainingLength);
                DecodeSubAckPayload(buffer, subAckPacket, ref remainingLength);
                return(subAckPacket);

            case Signatures.UnsubAck:
                if (_isServer)
                {
                    ValidateClientPacketExpected(packetSignature);
                }
                var unsubAckPacket = new UnsubAckPacket();
                DecodePacketIdVariableHeader(buffer, unsubAckPacket, ref remainingLength);
                return(unsubAckPacket);

            case Signatures.PingResp:
                if (_isServer)
                {
                    ValidateClientPacketExpected(packetSignature);
                }
                return(PingRespPacket.Instance);

            default:
                return(ThrowHelper.FromDecoderException_FirstPacketByteValueIsInvalid(packetSignature));
            }
        }
Example #22
0
        private static Packet DecodePacketInternal(DataReader reader, int packetSignature, ref uint remainingLength)
        {
            if (Signatures.IsPublish(packetSignature))
            {
                var qualityOfService =
                    (QualityOfService)((packetSignature >> 1) &
                                       0x3);  // take bits #1 and #2 ONLY and convert them into QoS value
                if (qualityOfService == QualityOfService.Reserved)
                {
                    throw new DecoderException(
                              $"Unexpected QoS value of {(int)qualityOfService} for {PacketType.PUBLISH} packet.");
                }

                bool duplicate = (packetSignature & 0x8) == 0x8; // test bit#3
                bool retain    = (packetSignature & 0x1) != 0;   // test bit#0
                var  packet    = new PublishPacket(qualityOfService, duplicate, retain);
                DecodePublishPacket(reader, packet, ref remainingLength);
                return(packet);
            }

            switch (packetSignature & 240)  // We don't care about flags for these packets
            {
            case Signatures.Subscribe& 240:
                var subscribePacket = new SubscribePacket();
                DecodePacketIdVariableHeader(reader, subscribePacket, ref remainingLength);
                DecodeSubscribePayload(reader, subscribePacket, ref remainingLength);
                return(subscribePacket);

            case Signatures.Connect:
                var connectPacket = new FbnsConnectPacket();
                DecodeConnectPacket(reader, connectPacket, ref remainingLength);
                return(connectPacket);

            case Signatures.ConnAck:
                var connAckPacket = new FbnsConnAckPacket();
                DecodeConnAckPacket(reader, connAckPacket, ref remainingLength);
                return(connAckPacket);

            case Signatures.SubAck:
                var subAckPacket = new SubAckPacket();
                DecodePacketIdVariableHeader(reader, subAckPacket, ref remainingLength);
                DecodeSubAckPayload(reader, subAckPacket, ref remainingLength);
                return(subAckPacket);

            case Signatures.Unsubscribe& 240:
                var unsubscribePacket = new UnsubscribePacket();
                DecodePacketIdVariableHeader(reader, unsubscribePacket, ref remainingLength);
                DecodeUnsubscribePayload(reader, unsubscribePacket, ref remainingLength);
                return(unsubscribePacket);

            case Signatures.PingResp:
                return(PingRespPacket.Instance);

            case Signatures.PubAck:
                var pubAckPacket = new PubAckPacket();
                DecodePacketIdVariableHeader(reader, pubAckPacket, ref remainingLength);
                return(pubAckPacket);

            default: return(null);
                //default:
                //    throw new DecoderException($"Packet type {packetSignature} not supported");
            }
        }
Example #23
0
 public PendingUnsubscribe(TaskCompletionSource <object> promise, string topic, UnsubscribePacket packet)
 {
     Promise = promise;
     Topic   = topic;
     retransmissionAction = new RetransmissionAction <UnsubscribePacket>()
     {
         OriginalPacket = packet
     };
 }
Example #24
0
        Packet DecodePacketInternal(IByteBuffer buffer, int packetSignature, ref int remainingLength, IChannelHandlerContext context)
        {
            if (Signatures.IsPublish(packetSignature))
            {
                var qualityOfService = (QualityOfService)((packetSignature >> 1) & 0x3); // take bits #1 and #2 ONLY and convert them into QoS value
                if (qualityOfService == QualityOfService.Reserved)
                {
                    throw new DecoderException($"Unexpected QoS value of {(int)qualityOfService} for {PacketType.PUBLISH} packet.");
                }

                bool duplicate = (packetSignature & 0x8) == 0x8; // test bit#3
                bool retain    = (packetSignature & 0x1) != 0;   // test bit#0
                var  packet    = new PublishPacket(qualityOfService, duplicate, retain);
                DecodePublishPacket(buffer, packet, ref remainingLength);
                return(packet);
            }

            switch (packetSignature) // strict match checks for valid message type + correct values in flags part
            {
            case Signatures.PubAck:
                var pubAckPacket = new PubAckPacket();
                DecodePacketIdVariableHeader(buffer, pubAckPacket, ref remainingLength);
                return(pubAckPacket);

            case Signatures.PubRec:
                var pubRecPacket = new PubRecPacket();
                DecodePacketIdVariableHeader(buffer, pubRecPacket, ref remainingLength);
                return(pubRecPacket);

            case Signatures.PubRel:
                var pubRelPacket = new PubRelPacket();
                DecodePacketIdVariableHeader(buffer, pubRelPacket, ref remainingLength);
                return(pubRelPacket);

            case Signatures.PubComp:
                var pubCompPacket = new PubCompPacket();
                DecodePacketIdVariableHeader(buffer, pubCompPacket, ref remainingLength);
                return(pubCompPacket);

            case Signatures.PingReq:
                this.ValidateServerPacketExpected(packetSignature);
                return(PingReqPacket.Instance);

            case Signatures.Subscribe:
                this.ValidateServerPacketExpected(packetSignature);
                var subscribePacket = new SubscribePacket();
                DecodePacketIdVariableHeader(buffer, subscribePacket, ref remainingLength);
                DecodeSubscribePayload(buffer, subscribePacket, ref remainingLength);
                return(subscribePacket);

            case Signatures.Unsubscribe:
                this.ValidateServerPacketExpected(packetSignature);
                var unsubscribePacket = new UnsubscribePacket();
                DecodePacketIdVariableHeader(buffer, unsubscribePacket, ref remainingLength);
                DecodeUnsubscribePayload(buffer, unsubscribePacket, ref remainingLength);
                return(unsubscribePacket);

            case Signatures.Connect:
                this.ValidateServerPacketExpected(packetSignature);
                var connectPacket = new ConnectPacket();
                DecodeConnectPacket(buffer, connectPacket, ref remainingLength, context);
                return(connectPacket);

            case Signatures.Disconnect:
                this.ValidateServerPacketExpected(packetSignature);
                return(DisconnectPacket.Instance);

            case Signatures.ConnAck:
                this.ValidateClientPacketExpected(packetSignature);
                var connAckPacket = new ConnAckPacket();
                DecodeConnAckPacket(buffer, connAckPacket, ref remainingLength);
                return(connAckPacket);

            case Signatures.SubAck:
                this.ValidateClientPacketExpected(packetSignature);
                var subAckPacket = new SubAckPacket();
                DecodePacketIdVariableHeader(buffer, subAckPacket, ref remainingLength);
                DecodeSubAckPayload(buffer, subAckPacket, ref remainingLength);
                return(subAckPacket);

            case Signatures.UnsubAck:
                this.ValidateClientPacketExpected(packetSignature);
                var unsubAckPacket = new UnsubAckPacket();
                DecodePacketIdVariableHeader(buffer, unsubAckPacket, ref remainingLength);
                return(unsubAckPacket);

            case Signatures.PingResp:
                this.ValidateClientPacketExpected(packetSignature);
                return(PingRespPacket.Instance);

            default:
                throw new DecoderException($"First packet byte value of `{packetSignature}` is invalid.");
            }
        }
Example #25
0
        private async Task OnConnack(MessageWebSocket ws)
        {
            var outStream       = ws.OutputStream;
            var loggedInUser    = _instaApi.Session.LoggedInUser;
            var subscribePacket = new SubscribePacket(
                _packetId++,
                new SubscriptionRequest("/ig_message_sync", QualityOfService.AtMostOnce),
                new SubscriptionRequest("/ig_send_message_response", QualityOfService.AtMostOnce)
                );

            await WriteAndFlushPacketAsync(subscribePacket, outStream);

            var unsubPacket = new UnsubscribePacket(_packetId++, "/ig_sub_iris_response");

            await WriteAndFlushPacketAsync(unsubPacket, outStream);

            subscribePacket = new SubscribePacket(_packetId++,
                                                  new SubscriptionRequest("/ig_sub_iris_response", QualityOfService.AtMostOnce));
            await WriteAndFlushPacketAsync(subscribePacket, outStream);

            var json = new JObject(
                new JProperty("seq_id", _seqId),
                new JProperty("snapshot_at_ms", _snapshotAt.ToUnixTimeMilliseconds()),
                new JProperty("snapshot_app_version", "web"),
                new JProperty("subscription_type", "message"));
            var jsonBytes         = GetJsonBytes(json);
            var irisPublishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
            {
                PacketId  = _packetId++,
                TopicName = "/ig_sub_iris",
                Payload   = jsonBytes.AsBuffer()
            };

            await WriteAndFlushPacketAsync(irisPublishPacket, outStream);

            json      = new JObject(new JProperty("unsub", new JArray($"ig/u/v1/{loggedInUser.Pk}")));
            jsonBytes = GetJsonBytes(json);
            var pubsubPublishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
            {
                PacketId  = _packetId++,
                TopicName = "/pubsub",
                Payload   = jsonBytes.AsBuffer()
            };

            await WriteAndFlushPacketAsync(pubsubPublishPacket, outStream);

            unsubPacket = new UnsubscribePacket(_packetId++, "/pubsub");
            await WriteAndFlushPacketAsync(unsubPacket, outStream);

            subscribePacket = new SubscribePacket(_packetId++,
                                                  new SubscriptionRequest("/pubsub", QualityOfService.AtMostOnce));
            await WriteAndFlushPacketAsync(subscribePacket, outStream);

            json                = new JObject(new JProperty("sub", new JArray($"ig/u/v1/{loggedInUser.Pk}")));
            jsonBytes           = GetJsonBytes(json);
            pubsubPublishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
            {
                PacketId  = _packetId++,
                TopicName = "/pubsub",
                Payload   = jsonBytes.AsBuffer()
            };
            await WriteAndFlushPacketAsync(pubsubPublishPacket, outStream);

            var clientSubscriptionId = Guid.NewGuid().ToString();

            json = new JObject(new JProperty("unsub",
                                             new JArray($"1/graphqlsubscriptions/17846944882223835/{{\"input_data\":{{\"client_subscription_id\":\"{clientSubscriptionId}\"}}}}")));
            jsonBytes = GetJsonBytes(json);
            var realtimeSubPublishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
            {
                PacketId  = _packetId++,
                TopicName = "/ig_realtime_sub",
                Payload   = jsonBytes.AsBuffer()
            };

            await WriteAndFlushPacketAsync(realtimeSubPublishPacket, outStream);

            unsubPacket = new UnsubscribePacket(_packetId++, "/ig_realtime_sub");
            await WriteAndFlushPacketAsync(unsubPacket, outStream);

            subscribePacket = new SubscribePacket(_packetId++,
                                                  new SubscriptionRequest("/ig_realtime_sub", QualityOfService.AtMostOnce));
            await WriteAndFlushPacketAsync(subscribePacket, outStream);

            json = new JObject(new JProperty("sub",
                                             new JArray($"1/graphqlsubscriptions/17846944882223835/{{\"input_data\":{{\"client_subscription_id\":\"{clientSubscriptionId}\"}}}}")));
            jsonBytes = GetJsonBytes(json);
            realtimeSubPublishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
            {
                PacketId  = _packetId++,
                TopicName = "/ig_realtime_sub",
                Payload   = jsonBytes.AsBuffer()
            };
            await WriteAndFlushPacketAsync(realtimeSubPublishPacket, outStream);

            StartPingingLoop(ws);
        }
Example #26
0
        private async void OnMessageReceived(MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args)
        {
            if (_pinging?.IsCancellationRequested ?? false)
            {
                return;
            }
            try
            {
                var    dataReader   = args.GetDataReader();
                var    outStream    = sender.OutputStream;
                var    loggedInUser = _instaApi.Session.LoggedInUser;
                Packet packet;
                try
                {
                    packet = StandalonePacketDecoder.DecodePacket(dataReader);
                }
                catch (Exception e)
                {
                    Debug.WriteLine(e);
                    Debug.WriteLine($"{nameof(SyncClient)}: Failed to decode packet.");
                    return;
                }

                switch (packet.PacketType)
                {
                case PacketType.CONNACK:
                    Debug.WriteLine($"{nameof(SyncClient)}: " + packet.PacketType);
                    var subscribePacket = new SubscribePacket(
                        _packetId++,
                        new SubscriptionRequest("/ig_message_sync", QualityOfService.AtMostOnce),
                        new SubscriptionRequest("/ig_send_message_response", QualityOfService.AtMostOnce)
                        );
                    await WriteAndFlushPacketAsync(subscribePacket, outStream);

                    var unsubPacket = new UnsubscribePacket(_packetId++, "/ig_sub_iris_response");
                    await WriteAndFlushPacketAsync(unsubPacket, outStream);

                    subscribePacket = new SubscribePacket(_packetId++,
                                                          new SubscriptionRequest("/ig_sub_iris_response", QualityOfService.AtMostOnce));
                    await WriteAndFlushPacketAsync(subscribePacket, outStream);

                    var random = new Random();
                    var json   = new JObject(
                        new JProperty("seq_id", _seqId),
                        new JProperty("snapshot_at_ms", _snapshotAt.ToUnixTimeMilliseconds()),
                        new JProperty("snapshot_app_version", "web"),
                        new JProperty("subscription_type", "message"));
                    var jsonBytes         = GetJsonBytes(json);
                    var irisPublishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
                    {
                        PacketId  = _packetId++,
                        TopicName = "/ig_sub_iris",
                        Payload   = Unpooled.CopiedBuffer(jsonBytes)
                    };
                    await WriteAndFlushPacketAsync(irisPublishPacket, outStream);

                    json      = new JObject(new JProperty("unsub", new JArray($"ig/u/v1/{loggedInUser.Pk}")));
                    jsonBytes = GetJsonBytes(json);
                    var pubsubPublishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
                    {
                        PacketId  = _packetId++,
                        TopicName = "/pubsub",
                        Payload   = Unpooled.CopiedBuffer(jsonBytes)
                    };
                    await WriteAndFlushPacketAsync(pubsubPublishPacket, outStream);

                    unsubPacket = new UnsubscribePacket(_packetId++, "/pubsub");
                    await WriteAndFlushPacketAsync(unsubPacket, outStream);

                    subscribePacket = new SubscribePacket(_packetId++,
                                                          new SubscriptionRequest("/pubsub", QualityOfService.AtMostOnce));
                    await WriteAndFlushPacketAsync(subscribePacket, outStream);

                    json                = new JObject(new JProperty("sub", new JArray($"ig/u/v1/{loggedInUser.Pk}")));
                    jsonBytes           = GetJsonBytes(json);
                    pubsubPublishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
                    {
                        PacketId  = _packetId++,
                        TopicName = "/pubsub",
                        Payload   = Unpooled.CopiedBuffer(jsonBytes)
                    };
                    await WriteAndFlushPacketAsync(pubsubPublishPacket, outStream);


                    Debug.WriteLine($"{nameof(SyncClient)}: " + packet.PacketType);
                    _ = Task.Run(async() =>
                    {
                        while (!_pinging.IsCancellationRequested)
                        {
                            try
                            {
                                await Task.Delay(TimeSpan.FromSeconds(8), _pinging.Token);
                                var pingPacket = PingReqPacket.Instance;
                                var pingBuffer = StandalonePacketEncoder.EncodePacket(pingPacket);
                                await sender.OutputStream.WriteAsync(pingBuffer);
                                await sender.OutputStream.FlushAsync();
                            }
                            catch (TaskCanceledException)
                            {
                                Debug.WriteLine("Stopped pinging sync server");
                                return;
                            }
                        }
                    });
                    return;

                case PacketType.PUBLISH:
                    var publishPacket = (PublishPacket)packet;
                    var payload       = publishPacket.Payload.ReadString(publishPacket.Payload.ReadableBytes, Encoding.UTF8);
                    if (publishPacket.TopicName == "/ig_message_sync")
                    {
                        var messageSyncPayload = JsonConvert.DeserializeObject <List <MessageSyncEventArgs> >(payload);
                        var latest             = messageSyncPayload.Last();
                        if (latest.SeqId > _seqId ||
                            latest.Data[0].Item.Timestamp > _snapshotAt)
                        {
                            _seqId      = latest.SeqId;
                            _snapshotAt = latest.Data[0].Item.Timestamp;
                        }
                        MessageReceived?.Invoke(this, messageSyncPayload);
                    }
                    Debug.WriteLine($"{nameof(SyncClient)} pub to {publishPacket.TopicName} payload: {payload}");

                    if (publishPacket.QualityOfService == QualityOfService.AtLeastOnce)
                    {
                        await WriteAndFlushPacketAsync(PubAckPacket.InResponseTo(publishPacket), outStream);
                    }
                    return;

                case PacketType.PINGRESP:
                    Debug.WriteLine("Got pong from Sync Client");
                    break;

                default:
                    Debug.WriteLine($"{nameof(SyncClient)}: " + packet.PacketType);
                    break;
                }
            }
            catch (Exception e)
            {
#if !DEBUG
                Crashes.TrackError(e);
#endif
                Debug.WriteLine("Exception occured when processing incoming sync message.");
                Debug.WriteLine(e);
            }
        }