SuperSocket源码解析之会话生命周期

摘要:
一个基本概念是会话是客户端和服务器之间通信的基本单元,也是套接字的封装。http协议中还有一种会话机制。它的主要作用是封装通信单元套接字,该套接字负责在服务器和客户端之间发送和接收消息。会话彼此独立,并具有唯一的SessionId标识符,该标识符维持客户端和服务器之间通信的生命周期。
一 基本概念

   会话(Session)是客户端与服务器进行通信的基本单元,也是一个Socket的封装,在http协议中也有Session机制,其主要作用封装一个通信单元socket,负责服务器与客户端消息发送与接收,会话之间相互独立互不干扰且拥有唯一SessionId标识,维护着客户与服务器通信的生命周期。

二 SocketSession

SocketSession是SuperSocket建立在消息收发层的会话,其主要作用在于客户与服务器通信,其生命周期主要由创建,初始化,启动,运行,关闭过程组成;

2.1 创建

SocketSession的创建源于服务器监听端口接收到一个客户端连接请求,取出该连接的Socket触发新客户端请求事件,且看代码

private IAppSession ProcessNewClient(Socket client, SslProtocols security)
{
//取出预先准备好的SocketAsyncEventArgsProxy代理
SocketAsyncEventArgsProxy socketEventArgsProxy;
if (!m_ReadWritePool.TryPop(out socketEventArgsProxy))
{
AppServer.AsyncRun(client.SafeClose);
if (AppServer.Logger.IsErrorEnabled)
AppServer.Logger.ErrorFormat("Max connection number {0} was reached!", AppServer.Config.MaxConnectionNumber);

return null;
}

ISocketSession socketSession;

if (security == SslProtocols.None)
socketSession = new AsyncSocketSession(client, socketEventArgsProxy);
else
socketSession = new AsyncStreamSocketSession(client, security, socketEventArgsProxy);

var session = CreateSession(client, socketSession);

//很大原因在于被连接过滤掉了这个地址,所以把拿出来的资源重置后在压入连接栈,并关闭端口
if (session == null)
{
socketEventArgsProxy.Reset();
this.m_ReadWritePool.Push(socketEventArgsProxy);
AppServer.AsyncRun(client.SafeClose);
return null;
}

socketSession.Closed += SessionClosed;

var negotiateSession = socketSession as INegotiateSocketSession;

if (negotiateSession == null)
{
if (RegisterSession(session))
{
AppServer.AsyncRun(() => socketSession.Start());
}

return session;
}

negotiateSession.NegotiateCompleted += OnSocketSessionNegotiateCompleted;
negotiateSession.Negotiate();

return null;
}

1)每一个客户端Socket都将交由SocketAsyncEventArgsProxy代理托管,该代理主要用着socket连接是否断开判断;

2)首先创建一个SocketSession实例,将该实例作为AppSession创建的参数;

SuperSocket源码解析之会话生命周期第1张

 3)创建AppSession 

SuperSocket源码解析之会话生命周期第2张

 2.2 初始化AppSession

SuperSocket源码解析之会话生命周期第3张

1) 初始化SocketSession和SocketAsyncProxy代理

SuperSocket源码解析之会话生命周期第4张

在初始化SocketSession过程中主要完成了 发送队列参数和代理设置;

2)SocketAsyncProxy代理初始化

SuperSocket源码解析之会话生命周期第5张

SuperSocket源码解析之会话生命周期第6张

当连接断开时将触发接收一次消息,即Socket最后一次操作处理将触发Socket是否断开验证,从而触发Session关闭

 2.3 启动会话

SuperSocket源码解析之会话生命周期第7张

这里将Start方法交给一个Task并行执行任务执行,也就是托管在线程池中,并处理Task终止异常;自此SocketSession将开始工作接收客户端发送的消息

2.4 工作

SuperSocket源码解析之会话生命周期第8张

其工作模式为:开始接收数据包,接收完成后交给AppSession处理该数据包,进而继续接收数据,此过程均是同步进行

2.5 会话关闭

首先会话关闭也就是Socket连接断开的原因有很多,如客户端主动断开,或者服务器过滤掉该会话,或者消息收发异常及其他严重异常也将导致该会话关闭终止,且看如何处理Socket的终止,

1)接收验证

首先在Socket上下文代理SocketAsyncProxy中将处理Socket最后一次接收,在每一次处理接收消息是将验证处理的数据包谁否完成,将验证该Socket连接的有效性,如图所示,如果没有任务数据包传输则判定该Socket失效,将关闭该会话

 SuperSocket源码解析之会话生命周期第9张

 2)发送验证

SuperSocket源码解析之会话生命周期第10张

如果发送的数据包为0那么也认定该Socket失效导致Session关闭

3)关闭Session

SuperSocket源码解析之会话生命周期第11张

SocketSession的关闭将触发AppServer会话关闭事件,进而触发AppSession的关闭,回收会话相关资源,代理等至此一次完整的会话周期完成

免责声明:文章转载自《SuperSocket源码解析之会话生命周期》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇centos 安装和配置 rabbitmqtp框架总体学习总结(一)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

springboot工程启动即执行一段代码

最近在做一个项目, 需要Tomcat启动后就执行一段代码 在这里需要用到CommandLineRunner这个接口, Spring boot的CommandLineRunner接口主要用于实现在应用初始化后,去执行一段代码块逻辑,这段初始化代码在整个应用生命周期内只会执行一次, 下面是具体办法 创建一个ApplicationStartupRunner类继承...

Kafka之SpringBoot集成Kafka实战

  在spring应用中如果需要订阅kafka消息,通常情况下我们不会直接使用kafka-client, 而是使用更方便的一层封装spring-kafka。  在spring-kafka在运行时会启动两类线程,一类是Consumer线程,另一类是Listener线程。前者用来直接调用kafka-client的poll()方法获取消息,后者才是调用我们代码中...

cookie,session原理,以及如何使用chrome查看。

首先,先补充下chrome浏览器的使用。 1.1、php源码: <?php $cookieDomain = '.elf.com'; setcookie('elf', 'im elf cookie', time()+300, '/', $cookieDomain); setcookie('aaa', 'aaaa', time()+10); 1.2...

C++中的动态绑定

C++中基类和派生类遵循类型兼容原则:即可用派生类的对象去初始化基类的对象,可用派生类的对象去初始化基类的引用,可用派生类对象的地址去初始化基类对象指针。 C++中动态绑定条件发生需要满足2个条件: 1:只有指定为虚函数的成员函数才能进行动态绑定,成员函数默认为非虚函数,非虚函数不能进行动态绑定 2:必须通过基类类型的引用或指针进行函数调用 基类类型引用和...

web安全测试之二

web系统安全性文性是个比较宽泛的概念,常见的测试关注点以目录设置、口令验证、授权登录、日志文件、Session与Cookie安全、异常操作、SQL注入、跨站脚本攻击XSS、跨站请求伪造CSRF等为主。 1:目录设置 目录设置对系统的安全性而言非常关键,一般认为在一些系统中通过某些小手段总能看到本不该展示的数据信息。例如:通过某些小手段总能看到本不该完成展...

Debug与Release的区别

  Debug版本包括调试信息,所以要比Release版本大很多(可能大数百K至数M)。至于是否需要DLL支持,主要看你采用的编译选项。如果是基于ATL的,则Debug和Release版本对DLL的要求差不多。如果采用的编译选项为使用MFC动态库,则需要MFC42D.DLL等库支持,而Release版本需要MFC42.DLL支持。Release  Buil...