无论是websocket还是传统socket 服务端创建的都是SocketListener实例
SocketListener的保护成员变量RequestHandler有虚函数SendHandshake和TryReceiveMessage
GameWebSocketHost 在创建SocketListener实例的时候通过 WebSocketRequestHandler对RequestHandler进行了赋值
WebSocketRequestHandler完成了握手过程
WebSocketRequestHandler 有一个成员变量
protected BaseHandshakeProcessor Handshake { get; set; }
负责在接收到数据之后完成握手的一系列动作Handshake 和WebSocketRequestHandler是通过WebSocketRequestHandler的函数
internal override void Bind(ISocket appServer)
{
if (Handshake != null)
{
Handshake.Handler = this;
}
base.Bind(appServer);
}
关联起来的
下面这个函数有个很关键的强制类型转换,当socket链接完成之后会完成握手过程并调用WebSocketRequestHandler的函数 SendHandshake
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的版本不同会有不同的实现
版权声明:本文为CSDN博主「weixin_33941350」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_33941350/article/details/92542619