Updating master client message handling

feature-npv2
Icedream 2014-05-22 17:08:07 +02:00
parent 420cecd594
commit a2f26ecb6b
1 changed files with 79 additions and 11 deletions

View File

@ -1,17 +1,92 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using log4net;
namespace NPSharp.Master.Messages namespace NPSharp.Master.Messages
{ {
public abstract class MasterClientMessage public abstract class MasterClientMessage
{ {
private static readonly ILog Log;
private byte[] _header = {0xFF, 0xFF, 0xFF, 0xFF};
static MasterClientMessage()
{
Log = LogManager.GetLogger(typeof (MasterClientMessage));
}
protected List<string> Properties { get; set; } protected List<string> Properties { get; set; }
public virtual byte[] Header
{
get { return _header; }
protected set { _header = value; }
}
internal string Name
{
get { return GetType().GetCustomAttribute<MasterClientMessageAttribute>().Name; }
}
internal MasterClientMessage Deserialize(Socket sock) internal MasterClientMessage Deserialize(Socket sock)
{ {
// TODO while (sock.Connected && !sock.Poll(2000, SelectMode.SelectRead))
{
}
if (!sock.Connected)
return null;
try
{
var buffer = new byte[1400]; // max packet size = 1400 bytes in dpmaster
var length = sock.Receive(buffer);
if (length == 0)
{
Log.Debug("Received 0 bytes");
return null;
}
if (length < 4)
{
Log.ErrorFormat("Received incomplete 4-byte header (received {0} bytes instead)", length);
throw new ProtocolViolationException("Received incomplete header");
}
var header = buffer.Take(4).ToArray();
var command = Encoding.ASCII.GetString(buffer, 4, length - 4).Trim();
var commandSplit = command.Split(new[] {'\t', '\r', '\n', '\0', ' '},
StringSplitOptions.RemoveEmptyEntries);
var commandName = commandSplit[0];
var commandArguments = commandSplit.Skip(1).ToArray();
// Search for a message class which fits to the commandName
var message =
(MasterClientMessage) Activator.CreateInstance(Assembly.GetExecutingAssembly()
.GetTypes()
.Single(
t =>
t.IsSubclassOf(typeof (MasterClientMessage)) &&
t.GetCustomAttribute<MasterClientMessageAttribute>()
.Name.Equals(commandName, StringComparison.OrdinalIgnoreCase)));
// Call the individual deserialize method
message.Deserialize(commandArguments);
message.Header = header;
return message;
}
catch (SocketException)
{
if (sock.Connected)
throw;
return null;
}
} }
internal byte[] SerializeInternal() internal byte[] SerializeInternal()
@ -28,13 +103,6 @@ namespace NPSharp.Master.Messages
return Name; return Name;
} }
public virtual byte[] Header { get { return new byte[] {0xFF, 0xFF, 0xFF, 0xFF}; } }
internal string Name
{
get { return GetType().GetCustomAttribute<MasterClientMessageAttribute>().Name; }
}
protected abstract void Deserialize(string[] arguments); protected abstract void Deserialize(string[] arguments);
} }
} }