我正在嘗試編寫一些基礎結構以方便更新服務器和客戶端之間的對象。這可能會在遊戲中使用,但是,我覺得這個問題並不完全針對遊戲(所以我在這裏問過)。網絡傳輸的高效(空間)序列化
爲了安全和效率的原因,我希望服務器有選擇地更新對象屬性。例如,對象的特定屬性可能僅對控制該對象的客戶端有用,因爲服務器只會用此信息更新「所有者」。或者,某些屬性可能需要發送給所有客戶端。爲了實現這一點,我已經定義指定的方式的自定義屬性,其中所述網絡應處理特性:
[AttributeUsage(AttributeTargets.Property)]
public class NetworkParameterAttribute : System.Attribute
{
public enum NetworkParameterType
{
ServerToOwner,
ServerToAll,
ServerToOwnerView,
OwnerToServer
}
private NetworkParameterType type;
public NetworkParameterType Type
{
get
{
return type;
}
}
public NetworkParameterAttribute(NetworkParameterType Type)
{
this.type = Type;
}
}
現在,在一個對象類我可以定義像這樣的屬性:
public class TestObject
{
[NetworkParameter(NetworkParameterAttribute.NetworkParameterType.ServerToAll)]
public int ID { get; set; }
[NetworkParameter(NetworkParameterAttribute.NetworkParameterType.ServerToOwner)]
public string Name { get; set; }
}
我可以然後寫一個簡單的功能,可以自動從物體抓住一組特定屬性:
public byte[] GetBytes(NetworkParameterAttribute.NetworkParameterType type)
{
MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
foreach (PropertyInfo info in this.GetType().GetProperties())
{
foreach (object attribute in info.GetCustomAttributes(true))
{
if (attribute is NetworkParameterAttribute &&
((NetworkParameterAttribute)attribute).Type == type)
{
formatter.Serialize(stream, info.GetValue(this, null));
}
}
}
byte[] buf = new byte[stream.Length];
Array.Copy(stream.GetBuffer(), buf, stream.Length);
return buf;
}
類似的功能可以把對象返回一起在receivi方面。我遇到的問題是序列化在空間使用方面效率很低。例如,從TestObject抓取ServerToAll屬性的結果是54個字節(而它可能只有4個)。
所以問題:是否有一種更有效的方法將對象序列化爲字節流,以達到我預期的目的?請注意,我不想寫很多序列化相關的代碼。
謝謝!
我喜歡這個想法,並且肯定希望將它與我已經完成的一起實施。有沒有辦法在屬性更改時自動設置該屬性? – DeusAduro 2011-04-17 18:51:17
我不認爲存在這樣的機制。您需要添加代碼。但是沒有一個標誌,我們可以複製數據。我會擴大答案。 – Dialecticus 2011-04-18 13:20:42