private async void OnMessageReceived(MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args) { if (_pinging?.IsCancellationRequested ?? false) { return; } try { var dataReader = args.GetDataReader(); Packet packet; try { packet = StandalonePacketDecoder.DecodePacket(dataReader); } catch (Exception e) { this.Log(e); this.Log("Failed to decode packet."); return; } this.Log("Received " + packet.PacketType); switch (packet.PacketType) { case PacketType.CONNACK: await OnConnack(sender); return; case PacketType.PUBLISH: await OnPublish(sender, packet); return; case PacketType.PINGRESP: break; } } catch (Exception e) { DebugLogger.LogException(e); this.Log("Exception occured when processing incoming sync message."); } }
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); } }