private async void ProcessMessage(HybridConnectionStream relayConnection, CancellationTokenSource cts) { // Bi-directional streams for read and write to the relay var reader = new StreamReader(relayConnection); var writer = new StreamWriter(relayConnection) { AutoFlush = true }; while (!cts.IsCancellationRequested) { // Read a message in input from the relay var message = await reader.ReadToEndAsync(); // Resolve address by invoking a service on the GIS server GisObject gisObject = JsonConvert.DeserializeObject <GisObject>(message); await new GisServer().ResolveAddressAsync(gisObject); // Write the message back to the relay message = JsonConvert.SerializeObject(gisObject); await writer.WriteLineAsync(message); } await relayConnection.CloseAsync(cts.Token); }
private async Task SendToRelay(HybridConnectionStream relayConnection, GisObject gisObject) { // Write the GIS object to the hybrid connection var writer = new StreamWriter(relayConnection) { AutoFlush = true }; string message = JsonConvert.SerializeObject(gisObject); await writer.WriteAsync(message); }
private async Task <GisObject> ReadFromRelay(HybridConnectionStream relayConnection) { // Read the GIS object from the hybrid connection var reader = new StreamReader(relayConnection); string message = await reader.ReadToEndAsync(); GisObject gisObject = JsonConvert.DeserializeObject <GisObject>(message); return(gisObject); }
public async Task ResolveAddressAsync(GisObject gisObject) { // Do reverse geolocation from coordinates to address // ... gisObject.Address = new Address { Line = "<AddressLine>", City = "<City>", ZipCode = "<ZipCode>", Country = "<Country>" }; }
public async Task ExecuteAsync(IServiceProvider serviceProvider) { IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = factory.CreateOrganizationService(context.UserId); Entity entity = (Entity)context.InputParameters["Target"]; GisObject gisObject = new GisObject { Latitude = (double)entity["Latitude"], Longitude = (double)entity["Longitude"] }; // Create a new hybrid connection client var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(keyName, key); var client = new HybridConnectionClient(new Uri($"sb://{relayNamespace}/{connectionName}"), tokenProvider); // Initiate the connection var relayConnection = await client.CreateConnectionAsync(); // Bi-directional sync of GIS data: // 1. Send a GIS object to the relay // 2. Receive a GIS object with the resolved address and update the entity // 3. Close the relay connection await new Task( () => SendToRelay(relayConnection, gisObject) .ContinueWith(async(t) => { GisObject resolved = await ReadFromRelay(relayConnection); ShowAddress(resolved); }) .ContinueWith(async(t) => await relayConnection.CloseAsync(CancellationToken.None)) .Start()); void ShowAddress(GisObject resolved) { var addr = resolved.Address; entity["Address"] = $"{addr.Line}, {addr.ZipCode} {addr.City}, {addr.Country}"; service.Update(entity); } }