Using Azure Application Insights with Unity

Unity 2017.1.0f3

Visual Studio 2015

Using .Net 4.6 experimental scripting for Unity

Update:

With some further investigation, I have found the root issue is that Unity is unable to establish an HTTPS connection with the Azure servers. Would appreciate any advice from people who may have experienced similar HTTPS issues previously.

{System.Security.Cryptography.CryptographicException: Store CA doesn’t exists.

at System.Security.Cryptography.X509Certificates.X509Store.Open (System.Security.Cryptography.X509Certificates.OpenFlags flags) [0x0009a] in
{Mono.Security.Protocol.Tls.TlsException: Invalid certificate received from server. Error code: 0xffffffff800b010a

at Mono.Security.Protocol.Tls.Handshake.Client.TlsServerCertificate.RemoteValidation (Mono.Security.Protocol.Tls.ClientContext context, Mo…}

{Mono.Security.Protocol.Tls.TlsException: Invalid certificate received from server. Error code: 0xffffffff800b010a

at Mono.Security.Protocol.Tls.RecordProtocol.EndReceiveRecord (System.IAsyncResult asyncResult) [0x00040] in <59bcb3a41e31492f91d951356644…}

{System.IO.IOException: The authentication or decryption has failed. —>

Mono.Security.Protocol.Tls.TlsException: Invalid certificate received from server. Error code: 0xffffffff800b010a

at Mono.Security.Protocol.Tls.RecordProtocol.EndReceiveRecord (Sy…}

{System.Net.Sockets.SocketException (0x80004005): An existing connection was forcibly closed by the remote host.

Original post:

We’re trying to do some advanced analytics for an academic research project which requires a higher level of detail than we can get through unity analytics. For this, we’re trying to use Application Insights on Azure.

We set up our unity project to use the .Net Framework 4.6 scripting API and installed the Microsoft.ApplicationInsights nuget package. We have successfully used this nuget package - NuGet Gallery | Unity.Newtonsoft.Json 7.0.0 - to get JSON functionality in our project.

However, we are having trouble getting application insights to work correctly. The same code works fine in a C# console application outside of unity. The unity project builds and runs, but the analytics packets are not being sent.

Using fiddler, I had a look at the requests being sent by application insights and noticed a difference between what unity and the console program sent. The C# console application sends a HTTP v1.1 / Keepalive request to setup an HTTPS connection with dc.services.visualstudio.com, then sends a request to /v2/track on that host. The unity application sends a HTTP v1.0 connection (no keep-alive) which gets the below response from the server. No request is sent to /v2/track.

HTTP/1.0 200 Connection Established

FiddlerGateway: Direct

StartTime: 18:30:21.609

Connection: close

I am unsure why the same library is having different network behaviour inside/outside unity and was wondering if anyone has successfully integrated application insights with unity. We have previously tried unity analytics, but we needed more extensive analytics than available, as well as alternatives like HockeyApp for unity but this does not support custom events on mobile.

Hi @hchokshi,

did you manage to solve this problem?

Cheers

We created an implementation of ITelemetryChannel that uses a subclass of Transmission that verifies against a bundled copy of the root certificate that the Application Insights SSL certificate is signed with.

    internal class UnityTelemetryTransmission : Transmission
    {
        private const string TelemetryCertResource = "Misc/TelemetryCert";

        private static readonly X509Certificate2 RootCertificate;

        static UnityTelemetryTransmission()
        {
            var cert = Resources.Load<TextAsset>(TelemetryCertResource);
            RootCertificate = new X509Certificate2(cert.bytes);
            Resources.UnloadAsset(cert);
        }

        public UnityTelemetryTransmission(Uri address, byte[] content, string contentType, string contentEncoding,
            TimeSpan timeout = new TimeSpan()) : base(address, content, contentType, contentEncoding, timeout)
        {
        }

        protected override WebRequest CreateRequest(Uri address)
        {
            var request = (HttpWebRequest) base.CreateRequest(address);
            request.ServerCertificateValidationCallback = (sender, certificate, chain, errors) =>
            {
                chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
                chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
                chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
                chain.ChainPolicy.VerificationTime = DateTime.Now;
                chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 0);

                chain.ChainPolicy.ExtraStore.Add(RootCertificate);
                return chain.Build((X509Certificate2) certificate);
            };
            return request;
        }
}

Use the TelemetryConfiguration constructor to specify the ITelemetryChannel you created.

If you are still looking for solutions I’ve created an App Insights library for Unity with some scene samples - GitHub - Unity3dAzure/UnityApplicationInsights: Application Insights for Unity. Track scene user flow, Unity UI button and Mixed Reality interaction events which you may find helpful.