不管是websocket仍是傳統socket 服務端建立的都是SocketListener實例web
SocketListener的保護成員變量RequestHandler有虛函數SendHandshake和TryReceiveMessagewebsocket
GameWebSocketHost 在建立SocketListener實例的時候經過 WebSocketRequestHandler對RequestHandler進行了賦值cookie
WebSocketRequestHandler完成了握手過程app
WebSocketRequestHandler 有一個成員變量socket
protected BaseHandshakeProcessor Handshake { get; set; }
負責在接收到數據以後完成握手的一系列動做Handshake 和WebSocketRequestHandler是經過WebSocketRequestHandler的函數ide
internal override void Bind(ISocket appServer) { if (Handshake != null) { Handshake.Handler = this; } base.Bind(appServer); }
關聯起來的函數
下面這個函數有個很關鍵的強制類型轉換,當socket連接完成以後會完成握手過程並調用WebSocketRequestHandler的函數 SendHandshakeui
protected override string CreateHandshakeData(DataToken dataToken) { ClientWebSocket webSocket = Handler.AppServer as ClientWebSocket; if (webSocket == null) { throw new Exception("ISocket is not WebSocket client"); } string host = webSocket.Settings.RemoteEndPoint.ToString(); string urlPath = webSocket.Settings.UrlPath; string origin = webSocket.Settings.Origin; string secKey1 = Encoding.ASCII.GetString(GenerateSecKey()); string secKey2 = Encoding.ASCII.GetString(GenerateSecKey()); byte[] secKey3 = GenerateSecKey(8); string protocol = webSocket.Settings.Protocol; string extensions = webSocket.Settings.Extensions; string cookie = ToCookiesString(webSocket.Settings.Cookies); dataToken.Socket.Handshake.ParamItems[HandshakeHeadKeys.SecSignKey] = GetResponseSecurityKey(secKey1, secKey2, secKey3); dataToken.Socket.Handshake.UriSchema = webSocket.Settings.Scheme; dataToken.Socket.Handshake.Host = host; dataToken.Socket.Handshake.UrlPath = urlPath; dataToken.Socket.Handshake.Protocol = protocol; dataToken.Socket.Handshake.HttpVersion = HandshakeHeadKeys.HttpVersion; dataToken.Socket.Handshake.Method = HandshakeHeadKeys.Method; dataToken.Socket.Handshake.WebSocketVersion = _version; dataToken.Socket.Handshake.ParamItems[HandshakeHeadKeys.Origin] = origin; dataToken.Socket.Handshake.ParamItems[HandshakeHeadKeys.SecKey1] = secKey1; dataToken.Socket.Handshake.ParamItems[HandshakeHeadKeys.SecKey2] = secKey2; ParseCookies(dataToken.Socket.Handshake, cookie); StringBuilder result = new StringBuilder(); result.AppendLine(string.Format("{0} {1} {2}", HandshakeHeadKeys.Method, urlPath, HandshakeHeadKeys.HttpVersion)); result.AppendLine(HandshakeHeadKeys.RespUpgrade00); result.AppendLine(HandshakeHeadKeys.RespConnection); result.AppendLine(string.Format("{0}: {1}", HandshakeHeadKeys.SecKey1, secKey1)); result.AppendLine(string.Format("{0}: {1}", HandshakeHeadKeys.SecKey2, secKey2)); result.AppendLine(string.Format("{0}: {1}", HandshakeHeadKeys.Host, host)); result.AppendLine(string.Format("{0}: {1}", HandshakeHeadKeys.Origin, !string.IsNullOrEmpty(origin) ? origin : host)); if (!string.IsNullOrEmpty(protocol)) { result.AppendLine(string.Format("{0}: {1}", HandshakeHeadKeys.SecProtocol, protocol)); } if (!string.IsNullOrEmpty(extensions)) { dataToken.Socket.Handshake.ParamItems[HandshakeHeadKeys.SecExtensions] = extensions; result.AppendLine(string.Format("{0}: {1}", HandshakeHeadKeys.SecExtensions, extensions)); } result.AppendLine(string.Format("{0}: {1}", HandshakeHeadKeys.SecVersion, _version)); if (!string.IsNullOrEmpty(cookie)) { result.AppendLine(string.Format("{0}: {1}", HandshakeHeadKeys.Cookie, cookie)); } result.AppendLine(); result.Append(Encoding.GetString(secKey3, 0, secKey3.Length)); return result.ToString(); }
關於CreateHandshakeData,websocket的版本不一樣會有不一樣的實現this