一 基本概念
會話(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的關閉,回收會話相關資源,代理等至此一次完整的會話周期完成