在网上找的记一下
public
abstract
class
Server {
static
readonly
ILog logger = LogManager.GetLogger(
typeof
(Server));
public
int
Port {
get
;
set
; }
public
event
ClientEventHandler OnClientAcceptEvent;
public
event
ClientEventHandler OnClientOnlineEvent;
public
event
ClientEventHandler OnClientRemoveEvent;
private
bool
bStarted;
static
private
int
NextClientId = 0;
private
TcpListener _listener;
protected
Dictionary<
int
, Client> id2client =
new
Dictionary<
int
, Client>();
private
List<Client> noHeartBeatClients =
new
List<Client>();
public
bool
HasHeartBeat;
private
int
CheckHeartBeatInterval = 30 * 1000;
// ms
protected
System.Timers.Timer CheckHeartBeatTimer =
new
System.Timers.Timer();
private
object
id2clientCS =
new
object
();
private
object
noHeartBeatClientsCS =
new
object
();
private
Server() {
CheckHeartBeatTimer.Elapsed += (o1, a1) => {
if
(HasHeartBeat ==
false
)
return
;
List<Client> kickClientList =
new
List<Client>();
lock
(id2clientCS) {
try
{
DateTime now = DateTime.Now;
foreach
(KeyValuePair<
int
, Client> pair
in
id2client) {
try
{
Client client = pair.Value;
TimeSpan offset = now - client.LastHeartBeat;
if
(client !=
null
&& client.State == Client.ConnectionState.Connected && offset.TotalMilliseconds > CheckHeartBeatInterval) {
kickClientList.Add(pair.Value);
logger.InfoFormat(
"检测到心跳超时: [IP]{0}, [ID]{1}, [Time]{2}"
, client.ClientIpAddress, pair.Key, DateTime.Now.ToString());
}
}
catch
{ }
}
}
catch
(Exception ex) {
logger.WarnFormat(
"心跳检测时发生异常: \n{0}"
, ex);
}
}
kickClientList.ForEach(p => p.Close());
lock
(noHeartBeatClientsCS) {
kickClientList.ForEach(c => noHeartBeatClients.RemoveAll(p => p.Id == c.Id));
}
};
}
public
Server(
int
port)
:
this
() {
this
.Port = port;
}
public
List<Client> Clients {
get
{
List<Client> result =
new
List<Client>();
lock
(id2clientCS) {
foreach
(Client each
in
id2client.Values) {
result.Add(each);
}
}
return
result;
}
}
public
virtual
void
Open() {
_listener =
new
TcpListener(Port);
logger.InfoFormat(
"Server#Open port={0}"
, Port);
try
{
_listener.Start();
if
(HasHeartBeat) {
CheckHeartBeatTimer.Stop();
CheckHeartBeatTimer.Interval = CheckHeartBeatInterval;
CheckHeartBeatTimer.Start();
}
_listener.BeginAcceptTcpClient(
new
AsyncCallback(OnAccept),
null
);
bStarted =
true
;
}
catch
(SocketException ex) {
logger.WarnFormat(
"服务器监听发生异常:{0}\nSocket ErrorCode: {1}\n提示:请检查端口是否已被占用"
, ex.Message, ex.ErrorCode);
throw
ex;
}
catch
(Exception ex) {
logger.Warn(ex);
throw
ex;
}
}
public
virtual
void
Close() {
try
{
if
(HasHeartBeat) {
CheckHeartBeatTimer.Stop();
}
_listener.Stop();
bStarted =
false
;
lock
(id2clientCS) {
foreach
(Client each
in
id2client.Values) {
try
{
if
(each !=
null
)each.Close(); }
catch
{ }
}
id2client.Clear();
}
}
catch
(Exception ex) {
logger.Warn(ex);
throw
ex;
}
}
private
void
OnAccept(IAsyncResult ar) {
try
{
Client client = CreateClient(NextClientId++, _listener.EndAcceptTcpClient(ar),
this
);
client.LastHeartBeat = DateTime.Now;
client.PostOfflineEvent += (obj, args) => RemoveClient(client);
lock
(id2clientCS) {
id2client.Add(client.Id, client);
}
lock
(noHeartBeatClientsCS) {
noHeartBeatClients.Add(client);
}
if
(OnClientAcceptEvent !=
null
) OnClientAcceptEvent(client);
}
catch
(ObjectDisposedException) { }
catch
(Exception ex) {
logger.Warn(ex);
}
finally
{
try
{
_listener.BeginAcceptTcpClient(
new
AsyncCallback(OnAccept),
null
);
}
catch
(Exception) {
// ignore
}
}
}
protected
abstract
Client CreateClient(
int
id, TcpClient tcpClient, Server server);
public
void
RemoveClient(Client client) {
if
(bStarted ==
false
)
return
;
lock
(id2clientCS) {
id2client.Remove(client.Id);
}
if
(OnClientRemoveEvent !=
null
) OnClientRemoveEvent(client);
}
public
void
GetHeartBeat(Client client) {
if
(HasHeartBeat ==
false
)
return
;
client.LastHeartBeat = DateTime.Now;
lock
(noHeartBeatClientsCS) {
int
index = noHeartBeatClients.FindIndex(p => p.Id == client.Id);
if
(index == -1)
return
;
try
{
if
(OnClientOnlineEvent !=
null
) OnClientOnlineEvent(client);
}
catch
(Exception ex) {
logger.Warn(ex);
}
noHeartBeatClients.RemoveAt(index);
}
}
}
http://www.doc88.com/p-4714417112965.html