pusher / pusher-websocket-dotnet

Pusher Channels Client Library for .NET
MIT License
112 stars 113 forks source link

Dynamic code generation from Newtonsoft.Json causes il2cpp incompatibility #83

Closed cdauphinee closed 3 years ago

cdauphinee commented 4 years ago

I tried to include the latest release in an iOS Unity build, and immediately receive the following exception upon connecting on a device:

NotSupportedException: System.Reflection.Emit.DynamicMethod::.ctor
System.Reflection.Emit.DynamicMethod..ctor (System.String name, System.Type returnType, System.Type[] parameterTypes, System.Type owner, System.Boolean skipVisibility)
Newtonsoft.Json.Utilities.DynamicReflectionDelegateFactory.CreateDynamicMethod (System.String name, System.Type returnType, System.Type[] parameterTypes, System.Type owner)
Newtonsoft.Json.Utilities.DynamicReflectionDelegateFactory.CreateParameterizedConstructor (System.Reflection.MethodBase method)
Newtonsoft.Json.Serialization.DefaultContractResolver.CreateObjectContract (System.Type objectType)
Newtonsoft.Json.Serialization.DefaultContractResolver.CreateContract (System.Type objectType)
System.Func`2[T,TResult].Invoke (T arg)
System.Collections.Concurrent.ConcurrentDictionary`2[TKey,TValue].GetOrAdd (TKey key, System.Func`2[T,TResult] valueFactory)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Boolean checkAdditionalContent)
Newtonsoft.Json.JsonConvert.DeserializeObject (System.String value, System.Type type, Newtonsoft.Json.JsonSerializerSettings settings)
Newtonsoft.Json.JsonConvert.DeserializeObject[T] (System.String value, Newtonsoft.Json.JsonSerializerSettings settings)
PusherClient.Connection.websocket_MessageReceived (System.Object sender, WebSocket4Net.MessageReceivedEventArgs e)
System.EventHandler`1[TEventArgs].Invoke (System.Object sender, TEventArgs e)
WebSocket4Net.WebSocket.ExecuteCommand (WebSocket4Net.WebSocketCommandInfo commandInfo)
WebSocket4Net.WebSocket.OnDataReceived (System.Byte[] data, System.Int32 offset, System.Int32 length)
SuperSocket.ClientEngine.AsyncTcpSes

It looks like Newtonsoft.Json's DeserializeObject isn't compatible with il2cpp, and the maintainers don't seem to have any intention of fixing it: https://github.com/JamesNK/Newtonsoft.Json/pull/2044

I checked a couple of our Unity projects, and it seems like they're all using the fork linked in the issue above.

I don't have any good proposals for how to fix this. Removing the Newtonsoft.Json dependency and requiring the consumer to provide a deserializer would make the library awkward and unwieldy for non-Unity consumers.

Maybe making a Unity fork is the only reasonable solution?

damdo commented 4 years ago

Hey Collin, thank you for reporting this. I left a message under the PR to see if the author has at least plans to get it merged. Otherwise, as you suggested, we might consider running on a fork, at least until they are made compatible.

damdo commented 4 years ago

Hey @cdauphinee,

I've just released a new version of pusher-websocket-unity that address the issue: https://github.com/pusher/pusher-websocket-unity/releases/tag/1.1.2%2B200211

for more details: https://github.com/pusher/pusher-websocket-unity/issues/15#issuecomment-584607270

Thank you.

bddesai commented 3 years ago

I have been facing the same issue for a while and searched on every nook and cranny of the internet to look for a solution. Here's what worked for me.

What's the difference?

Hope this helps. Cheers!