internal void Instantiates_With_The_Given_Data(MessageCode.Distributed code, byte[] message) { var r = new EmbeddedMessage(code, message); Assert.Equal(code, r.DistributedCode); Assert.Equal(message, r.DistributedMessage); }
/// <summary> /// Handles embedded messages from the server. /// </summary> /// <param name="message">The message.</param> public async void HandleEmbeddedMessage(byte[] message) { var code = MessageCode.Distributed.Unknown; try { var embeddedMessage = EmbeddedMessage.FromByteArray(message); code = embeddedMessage.DistributedCode; var distributedMessage = embeddedMessage.DistributedMessage; switch (code) { case MessageCode.Distributed.SearchRequest: // receiving a SearchRequest/3 from the server as an embedded message indicates that we are // operating as a branch root on the distributed network. SoulseekClient.DistributedConnectionManager.PromoteToBranchRoot(); var searchRequest = DistributedSearchRequest.FromByteArray(distributedMessage); _ = SoulseekClient.DistributedConnectionManager.BroadcastMessageAsync(message).ConfigureAwait(false); await SoulseekClient.SearchResponder.TryRespondAsync(searchRequest.Username, searchRequest.Token, searchRequest.Query).ConfigureAwait(false); break; default: Diagnostic.Debug($"Unhandled embedded message: {code}; {message.Length} bytes"); break; } } catch (Exception ex) { Diagnostic.Warning($"Error handling embedded message: {code}; {ex.Message}", ex); } }
void RunSerialize() { for (int i = 0; i < N; i++) { EmbeddedMessage embedded = EmbeddedMessage.CreateBuilder() .SetId(i) .BuildPartial(); TestMessage message = TestMessage.CreateBuilder() .SetId(1) .SetText(@"Test message included") .SetEmbedded(embedded) .BuildPartial(); using (MemoryStream ms = new MemoryStream()) { message.WriteTo(ms); TestMessage parsed = TestMessage.ParseFrom(ms.ToArray()); if (parsed.Embedded.Id != i) { throw new Exception("Invalid embedded value"); } } } }
/// <summary> /// Deserialize fields from a FastTransferStream. /// </summary> /// <param name="stream">A FastTransferStream.</param> public override void Deserialize(FastTransferStream stream) { this.propList = new PropList(stream); if (EmbeddedMessage.Verify(stream)) { this.embeddedMessage = new EmbeddedMessage(stream); } }
public void Parse_Throws_MessageReadException_On_Missing_Data() { var msg = new MessageBuilder() .WriteCode(MessageCode.Server.EmbeddedMessage) .Build(); var ex = Record.Exception(() => EmbeddedMessage.FromByteArray(msg)); Assert.NotNull(ex); Assert.IsType <MessageReadException>(ex); }
public void Parse_Throws_MessageException_On_Code_Mismatch() { var msg = new MessageBuilder() .WriteCode(MessageCode.Peer.BrowseRequest) .Build(); var ex = Record.Exception(() => EmbeddedMessage.FromByteArray(msg)); Assert.NotNull(ex); Assert.IsType <MessageException>(ex); }
private static EmbeddedMessage CreateSpaceEventEventMessage(Event spaceEvent) { var eventMessage = new EmbeddedMessage { Title = $"Upcoming event - {spaceEvent.Name}", ThumbnailUrl = spaceEvent.FeatureImgUrl, }; if (!string.IsNullOrEmpty(spaceEvent.Type?.Name)) { eventMessage.Fields.Add(new EmbeddedMessageField { Inline = true, Name = "Type of event", Content = spaceEvent.Type?.Name, }); } if (!string.IsNullOrEmpty(spaceEvent.EventTime.ToString())) { eventMessage.Fields.Add(new EmbeddedMessageField { Inline = true, Name = "Time of event UTC", Content = spaceEvent.EventTime.ToString(), }); } if (!string.IsNullOrEmpty(spaceEvent.Location)) { eventMessage.Fields.Add(new EmbeddedMessageField { Inline = true, Name = "Location", Content = spaceEvent.Location, }); } if (!string.IsNullOrEmpty(spaceEvent.Description)) { eventMessage.Fields.Add(new EmbeddedMessageField { Inline = false, Name = "Description", Content = spaceEvent.Description.ShortenTo(1024), }); } return(eventMessage); }
internal void Parse_Returns_Expected_Data(MessageCode.Distributed code, byte[] message) { var msg = new MessageBuilder() .WriteCode(MessageCode.Server.EmbeddedMessage) .WriteByte((byte)code) .WriteBytes(message) .Build(); var r = EmbeddedMessage.FromByteArray(msg); Assert.Equal(code, r.DistributedCode); Assert.Equal(message.Length + 1, BitConverter.ToInt32(r.DistributedMessage.Take(4).ToArray())); Assert.Equal((byte)code, r.DistributedMessage.Skip(4).Take(1).First()); Assert.Equal(message, r.DistributedMessage.Skip(5)); }
private static void AddFieldToEmbeddedMessageIfNotEmpty( EmbeddedMessage embeddedMessage, string title, string fieldValue, bool inline) { if (!string.IsNullOrEmpty(fieldValue)) { embeddedMessage.Fields.Add(new EmbeddedMessageField { Name = title, Content = fieldValue, Inline = inline }); } }
private static Task WriteObjectDetailsEmbeddedAsync(ReceivedMessage receivedMessage, AstronomicalObject foundObject) { var embeddedMessage = new EmbeddedMessage { Title = foundObject.Name, ThumbnailUrl = $"http://alasky.u-strasbg.fr/cgi/simbad-thumbnails/get-thumbnail.py?oid={foundObject.SimbadId}&size=200&legend=true" }; AddFieldToEmbeddedMessageIfNotEmpty(embeddedMessage, "Type:", foundObject.Type, inline: true); AddFieldToEmbeddedMessageIfNotEmpty(embeddedMessage, "Morphological Type:", foundObject.MorphologicalType, inline: true); var coordinates = foundObject.RaDecCoordinate != null ? $"RA: {Math.Round(foundObject.RaDecCoordinate.RightAscension, 5)}\r\nDEC: {Math.Round(foundObject.RaDecCoordinate.Declination, 5)}" : null; AddFieldToEmbeddedMessageIfNotEmpty(embeddedMessage, "Coordinates:", coordinates, inline: true); AddFieldToEmbeddedMessageIfNotEmpty(embeddedMessage, "Relative Velocity:", foundObject.RelativeVelocity?.ToString(), inline: true); var estimatedDistance = foundObject.MeasuredDistance != null ? $"{foundObject.MeasuredDistance}" : null; if (estimatedDistance != null) { var convertedDistance = AstronomicalDistanceUnitConverter.ConvertMeasurementWithErrorTo( foundObject.MeasuredDistance, AstronomicalDistanceUnitType.SI); if (convertedDistance.Value != foundObject.MeasuredDistance.Value) { estimatedDistance += $"\r\n{convertedDistance}"; } } AddFieldToEmbeddedMessageIfNotEmpty(embeddedMessage, "Estimated Distance:", estimatedDistance, inline: true); AddFieldToEmbeddedMessageIfNotEmpty(embeddedMessage, "Angular size:", foundObject.AngularDimensions?.ToString(), inline: true); AddFieldToEmbeddedMessageIfNotEmpty(embeddedMessage, "Fluxes [mag]:", FormatFluxes(foundObject), inline: false); AddFieldToEmbeddedMessageIfNotEmpty(embeddedMessage, "Secondary types:", string.Join(", ", foundObject.OtherTypes), inline: false); AddFieldToEmbeddedMessageIfNotEmpty(embeddedMessage, "Also known as:", string.Join(", ", foundObject.OtherNames).WithMaxLength(1024), inline: false); return(receivedMessage.Channel.SendMessageAsync(new SendMessage(embeddedMessage))); }
private static async Task <EmbeddedMessage> CreateEmbeddedMessageAsync(ReceivedMessage receivedMessage, string submissionId, AstrometrySubmissionResult calibrationData) { var objectsInImage = string.Join(", ", calibrationData.ObjectsInfField); await receivedMessage.Channel.SendMessageAsync($"Image analysis for submission {submissionId} completed. Here is the result:").ConfigureAwait(false); var embeddedMessage = new EmbeddedMessage { Title = "Astrometry.Net plate-solving result", }; embeddedMessage.Fields.Add(new EmbeddedMessageField { Name = "Coordinates at center of image:", Content = $"RA: {Math.Round(calibrationData.CalibrationData.Coordinates.RightAscension, 5)}\r\nDEC: {Math.Round(calibrationData.CalibrationData.Coordinates.Declination, 5)}\r\nAngle: {Math.Round(calibrationData.CalibrationData.Orientation, 3)}°", Inline = true }); embeddedMessage.Fields.Add(new EmbeddedMessageField { Name = "Angular size of image:", Content = $"{Math.Round(calibrationData.CalibrationData.Radius * 2, 5)}°", Inline = true }); embeddedMessage.Fields.Add(new EmbeddedMessageField { Name = "Pixel Scale:", Content = $"{calibrationData.CalibrationData.PixScale} arcsec/pixel", Inline = true }); embeddedMessage.Fields.Add(new EmbeddedMessageField { Name = "Some objects found in image:", Content = objectsInImage, Inline = false }); return(embeddedMessage); }
void RunSerialize() { for (int i = 0; i < N; i++) { FlatBufferBuilder messageBuffer = new FlatBufferBuilder(100); var text = messageBuffer.CreateString(@"Test message included"); int embeddedOffset = EmbeddedMessage.CreateEmbeddedMessage(messageBuffer, i); TestMessage.StartTestMessage(messageBuffer); TestMessage.AddText(messageBuffer, text.Value); TestMessage.AddEmbedded(messageBuffer, embeddedOffset); TestMessage.AddId(messageBuffer, i); int testMessage = TestMessage.EndTestMessage(messageBuffer); TestMessage.FinishTestMessageBuffer(messageBuffer, testMessage); string s = ""; for (int j = 0; j < messageBuffer.DataBuffer.Data.Length; j++) { s += messageBuffer.DataBuffer.Data[i].ToString() + ", "; } Debug.Log(s); using (MemoryStream ms = new MemoryStream(messageBuffer.DataBuffer.Data, 0, messageBuffer.DataBuffer.Data.Length)) { ByteBuffer byteBuffer = new ByteBuffer(ms.ToArray()); TestMessage parsed = TestMessage.GetRootAsTestMessage(byteBuffer); if (parsed.Embedded().Id() != i) { throw new Exception("Invalid embedded value"); } } } }
/// <summary> /// Handles incoming messages. /// </summary> /// <param name="sender">The <see cref="IMessageConnection"/> instance from which the message originated.</param> /// <param name="message">The message.</param> public async void HandleMessageRead(object sender, byte[] message) { var connection = (IMessageConnection)sender; var code = new MessageReader <MessageCode.Distributed>(message).ReadCode(); if (code != MessageCode.Distributed.SearchRequest && code != MessageCode.Distributed.EmbeddedMessage) { Diagnostic.Debug($"Distributed message received: {code} from {connection.Username} ({connection.IPEndPoint}) (id: {connection.Id})"); } else if (SoulseekClient.Options.DeduplicateSearchRequests) { var current = Convert.ToBase64String(message); if (DeduplicationHash == current) { return; } DeduplicationHash = current; } try { switch (code) { // if we are connected to a branch root, we will receive EmbeddedMessage/93. case MessageCode.Distributed.EmbeddedMessage: var embeddedMessage = EmbeddedMessage.FromByteArray(message); switch (embeddedMessage.DistributedCode) { // convert this message to a normal DistributedSearchRequest before forwarding. this functionality is based // on the observation that branch roots send embedded messages to children, while parents that are not a branch root // send a plain SearchRequest/3. case MessageCode.Distributed.SearchRequest: var embeddedSearchRequest = DistributedSearchRequest.FromByteArray(embeddedMessage.DistributedMessage); _ = SoulseekClient.DistributedConnectionManager.BroadcastMessageAsync(embeddedMessage.DistributedMessage).ConfigureAwait(false); await SoulseekClient.SearchResponder.TryRespondAsync(embeddedSearchRequest.Username, embeddedSearchRequest.Token, embeddedSearchRequest.Query).ConfigureAwait(false); break; default: Diagnostic.Debug($"Unhandled embedded message: {code} from {connection.Username} ({connection.IPEndPoint}); {message.Length} bytes"); break; } break; // if we are connected to anyone other than a branch root, we will receive SearchRequest/3. case MessageCode.Distributed.SearchRequest: var searchRequest = DistributedSearchRequest.FromByteArray(message); _ = SoulseekClient.DistributedConnectionManager.BroadcastMessageAsync(message).ConfigureAwait(false); await SoulseekClient.SearchResponder.TryRespondAsync(searchRequest.Username, searchRequest.Token, searchRequest.Query).ConfigureAwait(false); break; case MessageCode.Distributed.Ping: var pingResponse = DistributedPingResponse.FromByteArray(message); SoulseekClient.Waiter.Complete(new WaitKey(MessageCode.Distributed.Ping, connection.Username), pingResponse); break; case MessageCode.Distributed.BranchLevel: var branchLevel = DistributedBranchLevel.FromByteArray(message); if ((connection.Username, connection.IPEndPoint) == SoulseekClient.DistributedConnectionManager.Parent) { SoulseekClient.DistributedConnectionManager.SetParentBranchLevel(branchLevel.Level); } break; case MessageCode.Distributed.BranchRoot: var branchRoot = DistributedBranchRoot.FromByteArray(message); if ((connection.Username, connection.IPEndPoint) == SoulseekClient.DistributedConnectionManager.Parent) { SoulseekClient.DistributedConnectionManager.SetParentBranchRoot(branchRoot.Username); } break; case MessageCode.Distributed.ChildDepth: var childDepth = DistributedChildDepth.FromByteArray(message); SoulseekClient.Waiter.Complete(new WaitKey(Constants.WaitKey.ChildDepthMessage, connection.Key), childDepth.Depth); break; default: Diagnostic.Debug($"Unhandled distributed message: {code} from {connection.Username} ({connection.IPEndPoint}); {message.Length} bytes"); break; } } catch (Exception ex) { Diagnostic.Warning($"Error handling distributed message: {code} from {connection.Username} ({connection.IPEndPoint}); {ex.Message}", ex); } }
private static EmbeddedMessage CreateLaunchMessage(Launch launch) { var launchMessage = new EmbeddedMessage { Title = "Upcoming launch - " + string.Join(", ", launch.Name), ThumbnailUrl = launch.Image }; if (!string.IsNullOrEmpty(launch.LaunchServiceProvider?.Name)) { launchMessage.Fields.Add(new EmbeddedMessageField { Inline = true, Name = "Agency", Content = launch.LaunchServiceProvider?.Name }); } if (!string.IsNullOrEmpty(launch.Rocket?.Configuration?.FullName)) { launchMessage.Fields.Add(new EmbeddedMessageField { Inline = true, Name = "Rocket", Content = launch.Rocket?.Configuration?.FullName }); } if (!string.IsNullOrEmpty(launch.WindowStart.ToString()) && !string.IsNullOrEmpty(launch.WindowEnd.ToString())) { launchMessage.Fields.Add(new EmbeddedMessageField { Inline = true, Name = "Launch Window UTC", Content = $"{launch.WindowStart} to \r\n{launch.WindowEnd}" }); } if (!string.IsNullOrEmpty(launch.Pad?.Name)) { launchMessage.Fields.Add(new EmbeddedMessageField { Inline = true, Name = "Launch pad", Content = $"{launch.Pad?.Location?.Name} - {launch.Pad?.Name}" }); } var mission = launch.Mission; if (!string.IsNullOrEmpty(mission?.Name)) { launchMessage.Fields.Add(new EmbeddedMessageField { Inline = false, Name = $"Mission", Content = mission?.Name }); } if (!string.IsNullOrEmpty(mission?.Description)) { launchMessage.Fields.Add(new EmbeddedMessageField { Inline = false, Name = $"Mission Description", Content = mission?.Description?.ShortenTo(1024) ?? string.Empty }); } return(launchMessage); }