- Home /
Unity WCF Bug when sending integer using data contract
Hi folks,
I'm using WCF to communicate between Unity (on MacOS) and a Visual Studio Project. After getting the communication to work I stumbled upon a super mega weird bug.
Edit: If I do the exact same thing between two console applications on windows side, I don't experience these problems.
For some reason negative integers get messed up when sent from the Visual Studio Project to Unity. Also the Enumeration gets unloaded somehow.
So far I found out that the following integers come in wrong:
-90 becomes 166
-127 becomes 129
-128 becomes 128
I have made some screen shots to show you the results of my debugging party...
Data before sending it:

Data after receiving it:

Here is part of the Code I use:
The WCF Contract
using System.ServiceModel;
using System.Runtime.Serialization;
using System.Collections.Generic;
namespace ISI.VisualizationCommunication.Contract.LCPPSV02
{
[ServiceContract(CallbackContract = typeof(IVisualzationClientContractLCPPSV02), SessionMode = SessionMode.Required)]
public interface IVisualzationHostContractLCPPSV02
{
[OperationContract]
void Subscribe();
[OperationContract]
void Unsubscribe();
[OperationContract]
LHM GetLHM();
//[OperationContract]
//List<LHM> GetAllLhm();
//
//[OperationContract]
//LTE GetLte();
//
//[OperationContract]
//void ReceiveLHM(LHM lhm);
}
[ServiceContract]
public interface IVisualzationClientContractLCPPSV02
{
[OperationContract]
void Callback();
}
//This is the data definition for all our Load Carrier Objects
[DataContract]
public class LHM
{
public enum LhmType
{
cubic = 0,
round = 1
}
public LhmType lhmType;
[DataMember]
public int lhmLayer;
[DataMember]
public int lhmOrderID;
[DataMember]
public int lhmRotation;
[DataMember]
public int lhmPositionX;
[DataMember]
public int lhmPositionY;
[DataMember]
public int lhmLength;
[DataMember]
public int lhmWidth;
[DataMember]
public int lhmHeight;
}
The Host
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;
using System.Runtime.Serialization;
using ISI.VisualizationCommunication.Contract.LCPPSV02;
namespace WcfTestHost
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,AutomaticSessionShutdown = false,IncludeExceptionDetailInFaults = true)]
class WcfHost : IVisualzationHostContractLCPPSV02
{
IVisualzationClientContractLCPPSV02 Client = null;
ServiceHost Service = null;
public void Start()
{
Service = new ServiceHost(this, new Uri("net.tcp://localhost:16005"));
var Binding = new NetTcpBinding();
Binding.Security.Mode = SecurityMode.None;
Service.AddServiceEndpoint(
typeof(IVisualzationHostContractLCPPSV02),
Binding,
"LCPPSV02");
Service.Open();
Console.WriteLine("Service Started");
}
public void Subscribe()
{
try
{
Client = OperationContext.Current.GetCallbackChannel<IVisualzationClientContractLCPPSV02>();
Console.WriteLine("Client Connected");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
public void Unsubscribe()
{
Client = null;
}
public LHM GetLHM()
{
LHM lhm = new LHM();
lhm.lhmHeight = -128;
lhm.lhmWidth = -90;
lhm.lhmLength = -127;
return lhm;
}
}
}
The Client
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ServiceModel;
using System.Runtime.Serialization;
using ISI.VisualizationCommunication.Contract.LCPPSV02;
#region Mono
public class WCFTest : MonoBehaviour
{
WcfClient Client = null;
void Start()
{
Client = new WcfClient();
Client.Connect();
}
void Update()
{
if(Input.GetKeyDown(KeyCode.Space))
Client.GetData();
}
}
#endregion
#region WCF
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, AutomaticSessionShutdown = false, IncludeExceptionDetailInFaults=true)]
public class WcfClient : IVisualzationClientContractLCPPSV02
{
private IVisualzationHostContractLCPPSV02 Host = null;
private EndpointAddress endPoint = new EndpointAddress("net.tcp://VM-HB-01:16005/LCPPSV02");
public void Connect()
{
NetTcpBinding binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.None;
DuplexChannelFactory<IVisualzationHostContractLCPPSV02> channelFactory =
new DuplexChannelFactory<IVisualzationHostContractLCPPSV02>(
new InstanceContext(this),
binding,
endPoint);
try
{
Host = channelFactory.CreateChannel();
Host.Subscribe();
Debug.Log("Connection to server established successfully");
}
catch (Exception e)
{
Debug.Log("Trying to connect to server failed: " + e.Message);
}
}
public void Callback()
{}
public void GetData()
{
LHM list = Host.GetLHM();
Debug.Log("Pulled Data from Host");
}
}
#endregion
I would appreciate any help for resolving this problem. Also I've found two other posts about this, but no answer could be found till today (they already are quite old).
http://answers.unity3d.com/questions/327308/the-most-weird-bug-with-wcf.html
http://forum.unity3d.com/threads/really-weird-integer-problem-with-wcf.153580/
Edit: Just made another test, counting up from -260 to 0 and found this: At the point where -129 is reached, suddenly 255 are added on each and every int until 0 is reached. Apparantly the "-" is interpreted as 255 from this point on. So this must be a major bug I guess. The result is:
...
-128
-129
128
129
130
.....
Any special reason on why you're using a duplex wcf with net tcp binding?, have you tried with the most basic binding? httpbinding or wsbinding?. Another thing, have you tried to change your contracts to be Int32 ins$$anonymous$$d of int?. At the worst case scenario, you could return strings and cast them within you client, no sure if that could be a good fit for you
Hey, yes I've been trying to use int32 (without success). The Software where this technology will be used is very complex and later on we will need the duplex features.
For the people interested in a work around: I will now try to serialize the sent data to byte arrays (where hopefully no bug is present)
Your answer