public static UnsubAckPacket InResponseTo(UnsubscribePacket unsubscribePacket) { return new UnsubAckPacket { PacketId = unsubscribePacket.PacketId }; }
/// <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));; }
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); } }
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); }
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; }
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); } }
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)); }
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); }
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); }
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; }
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; }
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); }
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);
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)); } }
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"); } }
public PendingUnsubscribe(TaskCompletionSource <object> promise, string topic, UnsubscribePacket packet) { Promise = promise; Topic = topic; retransmissionAction = new RetransmissionAction <UnsubscribePacket>() { OriginalPacket = packet }; }
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."); } }
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); }
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); } }