我有一個系統,我可以在Windows和嵌入式系統之間通過不同的點到點通信通道交換消息,而且完全可以作爲非常標準的自定義序列化/反序列化函數完成,幾乎完全由手工完成,因爲這使得它很容易在Windows端的C#和嵌入的C端口之間移植。爲什麼我得到wcf反序列化的空數據?
現在我想添加一個大型網絡上的PC之間進行通信的塊。而不是做另一批相同的東西,使用TcpClient/TcpListener並跟蹤重疊的消息和響應,我決定看看WCF。
在看過很多關於這裏的信息以及其他文檔等信息之後,我想出了一個非常簡單的應用程序來交換消息,服務器包含一個接收和返回接口實例的函數,而不是一個固定的類。即使這個例子只有一種消息,因此只有一種類型是使用KnownType和ServiceKnownType屬性設置的,但我想知道可以發送幾十種不同類型的消息,並且我希望能夠添加它們隨着事物的發展相當容易。
雖然代碼不會生成錯誤,但在遠端實例化的對象沒有任何已發送的數據。我嘗試過數據包嗅探,看看我是否可以確認數據實際上在線路上,但我無法理解線路協議。所以我不知道數據在傳輸中還是在服務器中消失。如果我將代碼更改爲直接使用TestMessageType實例而不是使用接口,則它可以正常工作。
該解決方案由三個項目組成;一個「類型」程序集,然後引用該程序集的客戶端和服務器控制檯應用程序。類型程序集包含此代碼;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Runtime.Serialization;
namespace WCF_TCP_Sandpit
{
public interface ITestInterface
{
Int64 I64Value {get; set;}
}
[ServiceContract]
public interface IServer
{
[OperationContract]
[ServiceKnownType(typeof(TestMessageType))]
ITestInterface Test(ITestInterface msg);
}
[DataContract]
[KnownType(typeof(TestMessageType))]
public class TestMessageType : ITestInterface
{
Int64 _v1;
public long I64Value
{
get { return _v1; }
set { _v1 = value; }
}
public static Type[] KnownTypes()
{
return new Type[] { typeof(TestMessageType) };
}
}
}
服務器代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using WCF_TCP_Sandpit;
using System.Runtime.Serialization;
namespace Server
{
class Program : IServer
{
static void Main(string[] args)
{
using (ServiceHost serviceHost = new ServiceHost(typeof(Program), new Uri("net.tcp://127.0.0.1:9000")))
{
serviceHost.Open();
// The service can now be accessed.
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
}
}
#region IServer Members
public ITestInterface Test(ITestInterface msg)
{
ITestInterface reply = new TestMessageType();
reply.I64Value = msg.I64Value * 2;
return reply;
}
#endregion
}
}
和客戶端的代碼是
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WCF_TCP_Sandpit;
using System.ServiceModel;
namespace Client
{
class Program
{
static void Main(string[] args)
{
ITestInterface m,r;
int i = 0;
ChannelFactory<WCF_TCP_Sandpit.IServer> srv
= new ChannelFactory<WCF_TCP_Sandpit.IServer>
(new NetTcpBinding(), "net.tcp://127.0.0.1:9000");
WCF_TCP_Sandpit.IServer s;
s = srv.CreateChannel();
while (true)
{
m = new WCF_TCP_Sandpit.TestMessageType();
m.I64Value = i++;
r = s.Test(m);
Console.WriteLine("Sent " + m.I64Value + "; received " + r.I64Value);
System.Threading.Thread.Sleep(1000);
}
}
}
}
任何人都可以投在什麼地方出了錯一些輕?
當你檢查數據包(當它工作)它使用XML?我不記得wcf是否會使用xml序列化程序,但它可能會。 (從進一步閱讀看來,二進制序列化器使用ootb)。你有沒有試過把你的ITestMessage包裝成一個'Message'類(即讓ITestMessage成爲這個Message類的屬性) – wal 2012-07-18 15:10:05