Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

SignalR client not working in iOS #2933

Closed
BillyMutt opened this issue Sep 9, 2018 · 8 comments
Closed

SignalR client not working in iOS #2933

BillyMutt opened this issue Sep 9, 2018 · 8 comments
Labels
status: Waiting More info is needed or we're waiting for a response

Comments

@BillyMutt
Copy link

Based on the info here aspnet/Announcements#305 I was hoping to finally get my Xamarin iOS client working with ASP.Net Core SignalR, but still no luck. I get an exception when the client tries to connect to the hub:

//  Connect to the SignalR hub.
string url = $"http://{DataService.HostName}:{DataService.MainPort.ToString()}/hub";
try
{
    MediaHubConnection = new HubConnectionBuilder().WithUrl(url).Build();
}
catch (Exception e)
{ // Handle exception }

Exception: A suitable constructor for type Microsoft.AspNetCore.SignalR.Client.HttpConnectionFactory could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.

The code above works in the iPhone simulator, but crashes on the device itself.

I am using Visual Studio 15.8.0 with Xamarin iOS 11.14.0.13 on Windows 10; Visual Studio for Mac 7.6.1 Build 9 with Xamarin iOS 11.14.0.13 on the Mac. Latest released Nugets for AspNetCore SignalR (server and client).

Any help is highly appreciated.

@analogrelay analogrelay added the status: Investigate Investigation item label Sep 10, 2018
@analogrelay
Copy link
Contributor

Our sample worked on an iOS device last time I checked, but something might have broken here.

Can you try the sample app and see if it also shows the same issue? Maybe something is a little different about your application and that's causing the problem. Would you be able to post an application that reproduces the error? That would make it a lot easier to track this down.

@analogrelay analogrelay added status: Waiting More info is needed or we're waiting for a response and removed status: Investigate Investigation item labels Sep 10, 2018
@BillyMutt
Copy link
Author

Many thanks for responding. Let me try your sample app first, I'll check back as soon as I've had a chance to test it on an actual iOS device.

@BillyMutt
Copy link
Author

I was able to build and run your iOS sample, it works flawlessly on my iPhone. Next step for me is to identify the difference(s) between your sample and my app. The relevant code bits look identical, so I'm wondering if there is a clash somewhere between other dependencies. At least now I know it can work...

Once I find the issue on my side I'll post it here, maybe others have run into the same problem. Thanks for your help!

@analogrelay
Copy link
Contributor

If you're able to post a complete sample of an app that fails in this way somewhere, I'm happy to try to take a look and help out. Hope that helps find your issue! I think you're probably right that the issue lies in dependencies :).

If you're comfortable posting your dependencies, you could also just post your csproj file and the obj\project.assets.json file from the project. Please attach the files and do not just copy-paste them in as they can be quite large 😄 . See the first section of the Diagnostics Guide for some info on attaching files to GitHub comments.

@BillyMutt
Copy link
Author

I was able to reproduce the problem by making a small change to your sample app (apologies for the long post, but I wanted to include all the relevant detail):

I added a reference in the sample to one of my own assemblies (just some common, mostly legacy classes I use throughout my app). That assembly, in turn, references the following components:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.Serialization;

I modified the sample app very slightly to simply instantiate one of the classes in my assembly. Building the sample app now produces the following error:

Error Could not AOT the assembly '/Users/user141861/Library/Caches/Xamarin/mtbs/builds/iOSClient/20dea21417163e8e9d56adc21b28d8f9/obj/iPhone/Release/mtouch-cache/3-Build/System.Drawing.dll' iOSClient

That jogged my memory: to get around this build error, I had to change the build options for my app, and now also for the sample app. Changing the linker behavior from Link Framework SDKs Only to Link All gets rid of the error and the sample app build succeeds.

However, now when I run the sample app, I get the exact same exception that I get in my own app:

An error occurred while connecting: System.InvalidOperationException: A suitable constructor for type 'Microsoft.AspNetCore.SignalR.Client.HttpConnectionFactory' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite (System.Type serviceType, System.Type implementationType, Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteChain callSiteChain) <0x100dc68d0 + 0x00734> in <ef466db513bd4c67869506814ed622c5#98ca90be2f4ba6fc9197a6b1f218e40a>:0
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact (Microsoft.Extensions.DependencyInjection.ServiceDescriptor descriptor, System.Type serviceType, Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteChain callSiteChain) <0x100dc6500 + 0x00117> in <ef466db513bd4c67869506814ed622c5#98ca90be2f4ba6fc9197a6b1f218e40a>:0
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact (System.Type serviceType, Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteChain callSiteChain) <0x100dc6110 + 0x0005f> in <ef466db513bd4c67869506814ed622c5#98ca90be2f4ba6fc9197a6b1f218e40a>:0
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite (System.Type serviceType, Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteChain callSiteChain) <0x100dc5f70 + 0x000bb> in <ef466db513bd4c67869506814ed622c5#98ca90be2f4ba6fc9197a6b1f218e40a>:0
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.CreateServiceAccessor (System.Type serviceType) <0x100dcc7a0 + 0x00053> in <ef466db513bd4c67869506814ed622c5#98ca90be2f4ba6fc9197a6b1f218e40a>:0
at System.Collections.Concurrent.ConcurrentDictionary2[TKey,TValue].GetOrAdd (TKey key, System.Func2[T,TResult] valueFactory) <0x100362730 + 0x000b3> in <3c7b99a36820490fb2cbc5a6fc6b06d8#98ca90be2f4ba6fc9197a6b1f218e40a>:0
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService (System.Type serviceType, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope serviceProviderEngineScope) <0x100dcc6f0 + 0x0003b> in <ef466db513bd4c67869506814ed622c5#98ca90be2f4ba6fc9197a6b1f218e40a>:0
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService (System.Type serviceType) <0x100dcc680 + 0x0001f> in <ef466db513bd4c67869506814ed622c5#98ca90be2f4ba6fc9197a6b1f218e40a>:0
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService (System.Type serviceType) <0x100dc5120 + 0x0003f> in <ef466db513bd4c67869506814ed622c5#98ca90be2f4ba6fc9197a6b1f218e40a>:0
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T] (System.IServiceProvider provider) <0x100db78d0 + 0x0004b> in <4b47b422bc4c4615bbdebe1df9b21b0d#98ca90be2f4ba6fc9197a6b1f218e40a>:0
at Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilder.Build () <0x1009e90f0 + 0x0003f> in <1b2250b176e149ec8cda8e74d0229e3e#98ca90be2f4ba6fc9197a6b1f218e40a>:0
at iOSClient.ViewController+<ConnectDisconnectButton_TouchUpInside>d__32.MoveNext () <0x100198b90 + 0x002a3> in <79de77de19cf4e02af274cbf8100a615#98ca90be2f4ba6fc9197a6b1f218e40a>:0

As a final test, I reverted the sample app back to its original state by removing all traces of my assembly from the sample app, and built it again with the Link All linker setting. Same problem, the exception is thrown when trying to connect to the SignalR hub.

It appears, therefore, that the linker behavior change is the culprit. I may be able to refactor my code to remove this requirement, but in the meantime it would be interesting to know if there might be a fix or a workaround for this behavior. Let me know if you need additional information, I'd be more than happy to help track this down.

@analogrelay
Copy link
Contributor

I expect the problem is that the linker has removed code from HttpConnectionFactory that we need in order to activate it with DI. /cc @davidfowl

@BillyMutt
Copy link
Author

Yes, it certainly does look that way - I was able to refactor my code to remove the dependency on System.Drawing.dll, which allowed me to revert back to Link Framework SDKs Only. Everything builds and SignalR now works as expected on the iPhone. Happiness.

@analogrelay
Copy link
Contributor

Glad you found a solution to your problem!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
status: Waiting More info is needed or we're waiting for a response
Projects
None yet
Development

No branches or pull requests

2 participants