using System;
using System.Net;
namespace Sodao.FastSocket.Server
{
///
/// socket server.
///
///
public class SocketServer : SocketBase.BaseHost where TMessage : class, Messaging.IMessage
{
#region Private Members
private readonly SocketListener _listener = null;
private readonly ISocketService _socketService = null;
private readonly Protocol.IProtocol _protocol = null;
private readonly int _maxMessageSize;
private readonly int _maxConnections;
#endregion
#region Constructors
///
/// new
///
///
///
///
///
///
///
///
/// socketService is null.
/// protocol is null.
/// maxMessageSize
/// maxConnections
public SocketServer(int port,
ISocketService socketService,
Protocol.IProtocol protocol,
int socketBufferSize,
int messageBufferSize,
int maxMessageSize,
int maxConnections)
: base(socketBufferSize, messageBufferSize)
{
if (socketService == null) throw new ArgumentNullException("socketService");
if (protocol == null) throw new ArgumentNullException("protocol");
if (maxMessageSize < 1) throw new ArgumentOutOfRangeException("maxMessageSize");
if (maxConnections < 1) throw new ArgumentOutOfRangeException("maxConnections");
this._socketService = socketService;
this._protocol = protocol;
this._maxMessageSize = maxMessageSize;
this._maxConnections = maxConnections;
this._listener = new SocketListener(new IPEndPoint(IPAddress.Any, port), this);
this._listener.Accepted += this.OnAccepted;
}
#endregion
#region Private Methods
///
/// socket accepted handler
///
///
///
private void OnAccepted(ISocketListener listener, SocketBase.IConnection connection)
{
if (base.CountConnection() < this._maxConnections)
{
base.RegisterConnection(connection);
return;
}
SocketBase.Log.Trace.Info("too many connections.");
connection.BeginDisconnect();
}
#endregion
#region Override Methods
///
/// start
///
public override void Start()
{
base.Start();
this._listener.Start();
this._socketService.OnSend();
}
///
/// stop
///
public override void Stop()
{
this._listener.Stop();
base.Stop();
}
///
/// OnConnected
///
///
protected override void OnConnected(SocketBase.IConnection connection)
{
base.OnConnected(connection);
this._socketService.OnConnected(connection);
}
///
/// send callback
///
///
///
///
protected override void OnSendCallback(SocketBase.IConnection connection,
SocketBase.Packet packet, bool isSuccess)
{
base.OnSendCallback(connection, packet, isSuccess);
this._socketService.OnSendCallback(connection, packet, isSuccess);
}
///
/// OnMessageReceived
///
///
///
protected override void OnMessageReceived(SocketBase.IConnection connection,
SocketBase.MessageReceivedEventArgs e)
{
base.OnMessageReceived(connection, e);
int readlength;
TMessage message = null;
try { message = this._protocol.Parse(connection, e.Buffer, this._maxMessageSize, out readlength); }
catch (Exception ex)
{
this.OnConnectionError(connection, ex);
connection.BeginDisconnect(ex);
e.SetReadlength(e.Buffer.Count);
return;
}
if (message != null) this._socketService.OnReceived(connection, message);
e.SetReadlength(readlength);
}
///
/// OnDisconnected
///
///
///
protected override void OnDisconnected(SocketBase.IConnection connection, Exception ex)
{
base.OnDisconnected(connection, ex);
this._socketService.OnDisconnected(connection, ex);
}
///
/// on connection error
///
///
///
protected override void OnConnectionError(SocketBase.IConnection connection, Exception ex)
{
base.OnConnectionError(connection, ex);
this._socketService.OnException(connection, ex);
}
#endregion
}
}