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: 0xffffffff800b010aat 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 - https://www.nuget.org/packages/Unity.Newtonsoft.Json/ - 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.
Answer by hchokshi · Apr 13, 2018 at 09:59 AM
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.
Answer by korzen303 · Apr 12, 2018 at 10:34 AM
Hi @hchokshi,
big thanks for your reply and code snippet. We have got exactly same problem. However, no network guys in our $$anonymous$$m:(
So on Azure we have simply created an Application Insights resource and copied the Instrumentation $$anonymous$$ey to our code. Worked right away with the console app. Just to add that we want to connect from a standalone Windows desktop apps and not from devices.
I know that it might be trivial question but we are not sure, how to get the TelemetryCertResource certificate? Is this something we need to generate in Azure?
Thanks a lot
Answer by deadlyfingers · Dec 21, 2018 at 11:35 AM
If you are still looking for solutions I've created an App Insights library for Unity with some scene samples - https://github.com/Unity3dAzure/UnityApplicationInsights/ which you may find helpful.