大家好,我改用Json序列化了,这次序列化工作得很好,问题出在反序列化上,我有一个例外...
错误:
XmlException: Encountered an unexpected character '
System.Xml.XmlExceptionHelper.ThrowXmlException (System.Xml.XmlDictionaryReader reader, System.Xml.XmlException exception) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.XmlJsonReader.Read () (at <3abed3971fab48b2a085712365cc627f>:0)
System.Xml.XmlBaseReader.ReadEndElement () (at <3abed3971fab48b2a085712365cc627f>:0)
System.Xml.XmlBaseReader.ReadElementContentAsString () (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlReaderDelegator.ReadElementContentAsString () (at <3abed3971fab48b2a085712365cc627f>:0)
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <1f0c1ef1ad524c38bbc5536809c46b48>:0)
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <1f0c1ef1ad524c38bbc5536809c46b48>:0)
System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at <1f0c1ef1ad524c38bbc5536809c46b48>:0)
System.Runtime.Serialization.Json.JsonFormatReaderInterpreter.ReadValue (System.Type type, System.String name) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonFormatReaderInterpreter.ReadMembers (System.Int32 index, System.Runtime.Serialization.ClassDataContract classContract, System.Runtime.Serialization.BitFlagsGenerator expectedElements, System.Int32& memberIndex) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonFormatReaderInterpreter.ReadMembers (System.Runtime.Serialization.ClassDataContract classContract, System.Runtime.Serialization.ExtensionDataObject extensionData) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonFormatReaderInterpreter.ReadClass (System.Runtime.Serialization.ClassDataContract classContract) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonFormatReaderInterpreter.ReadFromJson (System.Runtime.Serialization.XmlReaderDelegator xmlReader, System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson context, System.Xml.XmlDictionaryString emptyDictionaryString, System.Xml.XmlDictionaryString[] memberNames) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonFormatReaderGenerator+CriticalHelper+<>c__DisplayClass0_0.<GenerateClassReader>b__0 (System.Runtime.Serialization.XmlReaderDelegator xr, System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson ctx, System.Xml.XmlDictionaryString emptyDictionaryString, System.Xml.XmlDictionaryString[] memberNames) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonClassDataContract.ReadJsonValueCore (System.Runtime.Serialization.XmlReaderDelegator jsonReader, System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson context) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonDataContract.ReadJsonValue (System.Runtime.Serialization.XmlReaderDelegator jsonReader, System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson context) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadJsonValue (System.Runtime.Serialization.DataContract contract, System.Runtime.Serialization.XmlReaderDelegator reader, System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson context) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson.ReadDataContractValue (System.Runtime.Serialization.DataContract dataContract, System.Runtime.Serialization.XmlReaderDelegator reader) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize (System.Runtime.Serialization.XmlReaderDelegator reader, System.String name, System.String ns, System.Type declaredType, System.Runtime.Serialization.DataContract& dataContract) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize (System.Runtime.Serialization.XmlReaderDelegator xmlReader, System.Type declaredType, System.Runtime.Serialization.DataContract dataContract, System.String name, System.String ns) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserialize (System.Runtime.Serialization.XmlReaderDelegator xmlReader, System.Type declaredType, System.Runtime.Serialization.DataContract dataContract, System.String name, System.String ns) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.DataContractJsonSerializer.InternalReadObject (System.Runtime.Serialization.XmlReaderDelegator xmlReader, System.Boolean verifyObjectName) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlObjectSerializer.InternalReadObject (System.Runtime.Serialization.XmlReaderDelegator reader, System.Boolean verifyObjectName, System.Runtime.Serialization.DataContractResolver dataContractResolver) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions (System.Runtime.Serialization.XmlReaderDelegator reader, System.Boolean verifyObjectName, System.Runtime.Serialization.DataContractResolver dataContractResolver) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions (System.Runtime.Serialization.XmlReaderDelegator reader, System.Boolean verifyObjectName) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject (System.Xml.XmlDictionaryReader reader) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject (System.IO.Stream stream) (at <3abed3971fab48b2a085712365cc627f>:0)
Server.Update () (at Assets/Scripts/Network/Server.cs:116)
代码:
从客户端类发送函数:
public void sendToServer(NMSG msg, int channelId)
{
if (!PacketHandler.packets.Contains(msg.GetType()))
{
Debug.Log("packet not registered");
return;
}
byte error;
byte[] buffer;
var stream = new MemoryStream();
var serializer = new DataContractJsonSerializer(typeof(NMSG));
serializer.WriteObject(stream, msg);
buffer = stream.ToArray();
int bufferSize = buffer.Length;
NetworkTransport.Send(hostId, connectionId, channelId, buffer, bufferSize, out error);
}
反序列化的代码:
MemoryStream memoryStream = new MemoryStream(recBuffer);
memoryStream.Position = 0;
var ser = new DataContractJsonSerializer(typeof(NMSG));
NMSG msg = (NMSG)ser.ReadObject(memoryStream);
onData(connectionId, channelId, recHostId, msg);
NMSG类别:
using System;
using System.Runtime.Serialization;
[DataContract]
[KnownType("GetKnownTypes")]
public abstract class NMSG
{
[DataMember]
private byte? discriminator = null;
public NMSG()
{
}
public NMSG(byte discriminator)
{
this.discriminator = discriminator;
}
public byte? getPacketId()
{
return this.discriminator;
}
public static Type[] GetKnownTypes()
{
return PacketHandler.packets.ToArray();
}
public abstract void HandleServer(NMSG msg, int connectionId);
public abstract void HandleClient(NMSG msg);
}
我发送到服务器的类
[DataContract]
public class NMSG_ConnectAccount : NMSG
{
[DataMember]
public string username;
[DataMember]
public string password;
public NMSG_ConnectAccount()
{
}
public NMSG_ConnectAccount(string username, string password) : base((byte)PacketHandler.packets.IndexOf(typeof(NMSG_ConnectAccount)))
{
this.username = username;
this.password = password;
}
public override void HandleClient(NMSG msg)
{
}
public override void HandleServer(NMSG msg, int connectionId)
{
NMSG_ConnectAccount cmsg = (NMSG_ConnectAccount)msg;
Server server = Server.getServer();
Mysql mysql = server.mysql;
password = EncryptionUtils.MD5Hash(password);
mysql.openMysqlConnection();
MySqlCommand commandsql = new MySqlCommand("SELECT * FROM users WHERE username = '" + cmsg.username + "'", mysql.con);
MySqlDataReader MyReader = commandsql.ExecuteReader();
string activated = "";
string mpassword = "";
string muser = "";
if (MyReader.Read())
{
activated = MyReader["confirmed"].ToString();
mpassword = MyReader["password"].ToString();
muser = MyReader["username"].ToString();
}
MyReader.Close();
if (mpassword != cmsg.password || cmsg.username != muser)
{
server.sendToPlayer(new NMSG_ConnectionMessage(cmsg.username,false,false), server.reliableChannel, connectionId);
return;
}
if (server.users.ContainsKey(connectionId))
server.users[connectionId].setName(muser);
else
return;
if (activated == "False")
{
server.sendToPlayer(new NMSG_ConnectionMessage(cmsg.username,false,true), server.reliableChannel, connectionId);
return;
}
server.users[connectionId].pData = new PlayerData(cmsg.username);
server.users[connectionId].isAuth = true;
server.sendToPlayer(new NMSG_ConnectionMessage(cmsg.username,true,false), server.reliableChannel, connectionId);
}
}
预先感谢您的帮助
答案 0 :(得分:0)
这就是我要做的:
packetHandler类:
public class PacketHandler
{
public static List<System.Type> packets = new List<System.Type>();
public PacketHandler()
{
registerPacket(typeof(NMSG_CreatePlayer));
registerPacket(typeof(NMSG_UpdatePlayer));
registerPacket(typeof(NMSG_UpdatePlayerState));
registerPacket(typeof(NMSG_CreateAccount));
registerPacket(typeof(NMSG_RegisterMessage));
registerPacket(typeof(NMSG_ConnectAccount));
registerPacket(typeof(NMSG_ConnectionMessage));
registerPacket(typeof(NMSG_ActivateAccountProcess));
registerPacket(typeof(NMSG_DisconnectAccount));
registerPacket(typeof(NMSG_PlayerDataTransmission));
registerPacket(typeof(NMSG_UpdateAccountData));
registerPacket(typeof(NMSG_UpdateInventory));
registerPacket(typeof(NMSG_UpdateItemInventory));
registerPacket(typeof(NMSG_RefreshShop));
registerPacket(typeof(NMSG_BuyRequest));
}
public bool registerPacket(System.Type packet)
{
if(!packet.GetType().IsInstanceOfType(typeof(NMSG)))
{
throw new System.Exception("Type of packet must be NMSG");
}
if(packets.Count >= 256)
{
throw new System.Exception("Packets count exceed limit of 255");
}
if(packets.Contains(packet))
{
throw new System.Exception("Packet already registered");
}
packets.Add(packet);
return true;
}
}
服务器类
private void Start()
{
INSTANCE = this;
NetworkSide.side = NetworkSide.Side.SERVER;
mysql = new Mysql();
if (!mysql.openMysqlConnection())
{
Debug.Log("ERROR- Server data center not active server closed...");
return;
}
serverProperties = new ServerProperties();
NetworkTransport.Init();
ConnectionConfig cc = new ConnectionConfig();
reliableChannel = cc.AddChannel(QosType.Reliable);
unreliableChannel = cc.AddChannel(QosType.Unreliable);
HostTopology topo = new HostTopology(cc, serverProperties.MAX_CONNECTION);
hostId = NetworkTransport.AddHost(topo, serverProperties.port, null);
packetHandler = new PacketHandler();
registerCommand(new CommandHelp("help", "display all commands", null));
registerCommand(new CommandGive("give", "give item to specified player", new string[] { "<Username>", "<ItemId>" }));
registerCommand(new CommandStop("stop", "stop server", null));
EventManager.registerEvent(new DeathEvent());
EventManager.registerEvent(new AreaQuitEvent());
EventManager.registerEvent(new AreaEnterEvent());
EventManager.registerEvent(new DamageEvent());
ItemInitializer.loadItems();
world = new World();
world.Load();
Debug.Log("Server started in port : " + serverProperties.port);
Debug.Log("Max Slot = " + serverProperties.MAX_CONNECTION);
Debug.Log("You can configurate server data in serverProperties.properties");
isStarted = true;
}
如您所见,所有NMSG类都已在启动功能中大量注册
客户端:
void Start()
{
client = this;
packetHandler = new PacketHandler();
NetworkSide.side = NetworkSide.Side.CLIENT;
EventManager.registerEvent(new AreaQuitEvent());
EventManager.registerEvent(new AreaEnterEvent());
ConnectToServer("127.0.0.1",port);
}
与客户相同
现在我将调试列表“数据包”以查看其包含的内容
服务器控制台:
packets count (Server) 15
NMSG_CreatePlayer
NMSG_UpdatePlayer
NMSG_UpdatePlayerState
NMSG_CreateAccount
NMSG_RegisterMessage
NMSG_ConnectAccount
NMSG_ConnectionMessage
NMSG_ActivateAccountProcess
NMSG_DisconnectAccount
NMSG_PlayerDataTransmission
NMSG_UpdateAccountData
NMSG_UpdateInventory
NMSG_UpdateItemInventory
NMSG_RefreshShop
NMSG_BuyRequest
UnityEngine.Debug:Log(Object)
Server:Start() (at Assets/Scripts/Network/Server.cs:90)
客户端控制台:
packets count (Client) 15
NMSG_CreatePlayer
NMSG_UpdatePlayer
NMSG_UpdatePlayerState
NMSG_CreateAccount
NMSG_RegisterMessage
NMSG_ConnectAccount
NMSG_ConnectionMessage
NMSG_ActivateAccountProcess
NMSG_DisconnectAccount
NMSG_PlayerDataTransmission
NMSG_UpdateAccountData
NMSG_UpdateInventory
NMSG_UpdateItemInventory
NMSG_RefreshShop
NMSG_BuyRequest
UnityEngine.Debug:Log(Object)
Client:Start() (at Assets/Scripts/Network/Client.cs:64)
所以数据包列表包含的内容不可能为空,我不明白为什么它不起作用...
答案 1 :(得分:0)
问题解决了,我现在使用的是手动序列化,它更快,占用空间更少,我向所有使用序列化发送网络对象的人推荐这种方法。