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

一 基本概念

会话(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创建的参数;

3)创建AppSession

2.2 初始化AppSession

1) 初始化SocketSession和SocketAsyncProxy代理

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

2)SocketAsyncProxy代理初始化

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

2.3 启动会话

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

2.4 工作

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

2.5 会话关闭

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

1)接收验证

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

2)发送验证

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

3)关闭Session

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

时间: 2024-10-27 05:20:46

SuperSocket源码解析之会话生命周期的相关文章

React 源码剖析系列 - 生命周期的管理艺术

目前,前端领域中 React 势头正盛,很少能够深入剖析内部实现机制和原理. 本系列文章 希望通过剖析 React 源码,理解其内部的实现原理,知其然更要知其所以然. 对于 React,其组件生命周期(Component Lifecycle)是它的核心概念,本文从源码入手,来剖析 React 生命周期的管理艺术. 阅读本文需要对 React 有一定的了解,如果你不知何为组件的生命周期,请详读 React 生命周期的文档. 如果你对 React 组件的生命周期存在些许疑惑,如生命周期如何顺序管理:

CVB生命周期(APIView源码解析)

目录 Django项目中的代码如下 APIView源码解析 源码解析总结 Django项目中的代码如下 urls.py中: from django.conf.urls import url from app import views urlpatterns = [ url(r'^test/$', views.APIViewSourceCode.as_view()), ] views.py中: from rest_framework.views import APIView class APIVi

dubbo源码解析-zookeeper创建节点

前言 在之前dubbo源码解析-本地暴露中的前言部分提到了两道高频的面试题,其中一道dubbo中zookeeper做注册中心,如果注册中心集群都挂掉,那发布者和订阅者还能通信吗?在上周的dubbo源码解析-zookeeper连接中已经讲到,这周解析的是另一道,即服务提供者能实现失效踢出是根据什么原理? 上周就有朋友问到我,为什么我的源码解析总是偏偏要和面试题挂上钩呢?原因很简单 1.dubbo源码这么多,试问你从哪里做为切入点?也就是说该从哪里看起?所以以面试题为切入点,你可以理解为我是在回答"

Mybatis源码解析(四) —— SqlSession是如何实现数据库操作的?

Mybatis源码解析(四) -- SqlSession是如何实现数据库操作的? ??如果拿一次数据库请求操作做比喻,那么前面3篇文章就是在做请求准备,真正执行操作的是本篇文章要讲述的内容.正如标题一样,本篇文章最最核心的要点就是 SqlSession实现数据库操作的源码解析.但按照惯例,我这边依然列出如下的问题: 1. SqlSession 是如何被创建的? 每次的数据库操作都会创建一个新的SqlSession么?(也许有很多同学会说SqlSession是通过 SqlSessionFactor

Flume-ng源码解析之Channel组件

如果还没看过Flume-ng源码解析之启动流程,可以点击Flume-ng源码解析之启动流程 查看 1 接口介绍 组件的分析顺序是按照上一篇中启动顺序来分析的,首先是Channel,然后是Sink,最后是Source,在开始看组件源码之前我们先来看一下两个重要的接口,一个是LifecycleAware ,另一个是NamedComponent 1.1 LifecycleAware @[email protected] interface LifecycleAware {  public void s

源码解析:dialog, popupwindow, 和activity 的第一个view是怎么来的?

问题 在慢慢熟悉android 的过程中,发现一个view 或者layout的初始化,或者构造的流程还是比较清楚的,也就是加到父控件中,然后就开始了对应的生命周期.但是整个界面的父控件,或者说系统的第一个view, 是怎么来的,如何初始化和绘制的呢? 概述 概述:带着困扰我的问题,在前文的基础上,继续分析应用界面和framework的关系,通过分析viewrootimpl 的来源,并结合dialog, popupwindow, 和activity 的 根view的创建流程,回答了问题界面的根vi

Spring IoC源码解析——Bean的创建和初始化

Spring介绍 Spring(http://spring.io/)是一个轻量级的Java 开发框架,同时也是轻量级的IoC和AOP的容器框架,主要是针对JavaBean的生命周期进行管理的轻量级容器,可以单独使用,也可以和Struts框架,MyBatis框架等组合使用. IoC介绍 IoC是什么 Ioc-Inversion of Control,即"控制反转",不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控

YTKNetwork源码解析

对于iOS开发者来说,就算是没有用过YTKNetwork框架,应该也见过,听过了.它是猿题库技术团队开源的一个网络请求框架,内部封装了AFNetworking.它把每个请求实例化,管理它的生命周期,也可以管理多个请求. 在正式讲解源码之前,我会先讲一下该框架所用的架构和设计模式.我总觉得对架构和设计有一定的了解的话,会有助于对源码的理解. 1. 架构 先上图: YTKRequest架构图 在这里简单说明一下: YTKNetwork框架将每一个请求实例化,YTKBaseRequest是所有请求类的

android源码解析之(十五)-->Activity销毁流程

继续我们的源码解析,上一篇文章我们介绍了Activity的启动流程,一个典型的场景就是Activity a 启动了一个Activity b,他们的生命周期回调方法是: onPause(a) –> onCreate(b) –> onStart(b) –> onResume(b) –> onStop(a) 而我们根据源码也验证了这样的生命周期调用序列,那么Activity的销毁流程呢?它的生命周期的调用顺序又是这样的呢? 这里我们我做一个简单的demo,让一个Activity a启动A