本文整理汇总了C#中StringBuilder.AppendFormatWithCrCf方法的典型用法代码示例。如果您正苦于以下问题:C# StringBuilder.AppendFormatWithCrCf方法的具体用法?C# StringBuilder.AppendFormatWithCrCf怎么用?C# StringBuilder.AppendFormatWithCrCf使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类StringBuilder
的用法示例。
在下文中一共展示了StringBuilder.AppendFormatWithCrCf方法的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: Handshake
public override bool Handshake(IWebSocketSession session, WebSocketReceiveFilterBase previousFilter, out IReceiveFilter<IWebSocketFragment> dataFrameReader)
{
if (!VersionTag.Equals(session.SecWebSocketVersion) && NextProcessor != null)
{
return NextProcessor.Handshake(session, previousFilter, out dataFrameReader);
}
dataFrameReader = null;
session.ProtocolProcessor = this;
if (!session.AppServer.ValidateHandshake(session, session.Items.GetValue<string>(OriginKey, string.Empty)))
return false;
var secWebSocketKey = session.Items.GetValue<string>(WebSocketConstant.SecWebSocketKey, string.Empty);
if (string.IsNullOrEmpty(secWebSocketKey))
{
return false;
}
var responseBuilder = new StringBuilder();
string secKeyAccept = string.Empty;
try
{
secKeyAccept = Convert.ToBase64String(SHA1.Create().ComputeHash(Encoding.ASCII.GetBytes(secWebSocketKey + m_Magic)));
}
catch (Exception)
{
return false;
}
responseBuilder.AppendWithCrCf(WebSocketConstant.ResponseHeadLine10);
responseBuilder.AppendWithCrCf(WebSocketConstant.ResponseUpgradeLine);
responseBuilder.AppendWithCrCf(WebSocketConstant.ResponseConnectionLine);
responseBuilder.AppendFormatWithCrCf(WebSocketConstant.ResponseAcceptLine, secKeyAccept);
var subProtocol = session.GetAvailableSubProtocol(session.Items.GetValue<string>(WebSocketConstant.SecWebSocketProtocol, string.Empty));
if (!string.IsNullOrEmpty(subProtocol))
responseBuilder.AppendFormatWithCrCf(WebSocketConstant.ResponseProtocolLine, subProtocol);
responseBuilder.AppendWithCrCf();
byte[] data = Encoding.UTF8.GetBytes(responseBuilder.ToString());
session.SendRawData(data, 0, data.Length);
dataFrameReader = new WebSocketDataFrameReceiveFilter();
return true;
}
示例2: Handshake
public override bool Handshake(IWebSocketSession session, WebSocketReceiveFilterBase previousFilter, out IReceiveFilter<IWebSocketFragment> dataFrameReader)
{
var secKey1 = session.Items.GetValue<string>(WebSocketConstant.SecWebSocketKey1, string.Empty);
var secKey2 = session.Items.GetValue<string>(WebSocketConstant.SecWebSocketKey2, string.Empty);
dataFrameReader = null;
if (string.IsNullOrEmpty(secKey1) && string.IsNullOrEmpty(secKey2) && NextProcessor != null)
{
return NextProcessor.Handshake(session, previousFilter, out dataFrameReader);
}
session.ProtocolProcessor = this;
if (!session.AppServer.ValidateHandshake(session, session.Items.GetValue<string>(WebSocketConstant.Origin, string.Empty)))
return false;
var secKey3 = session.Items.GetValue<byte[]>(WebSocketConstant.SecWebSocketKey3, m_ZeroKeyBytes);
var responseBuilder = new StringBuilder();
responseBuilder.AppendWithCrCf(WebSocketConstant.ResponseHeadLine00);
responseBuilder.AppendWithCrCf(WebSocketConstant.ResponseUpgradeLine);
responseBuilder.AppendWithCrCf(WebSocketConstant.ResponseConnectionLine);
if (!string.IsNullOrEmpty(session.Origin))
responseBuilder.AppendFormatWithCrCf(WebSocketConstant.ResponseOriginLine, session.Origin);
responseBuilder.AppendFormatWithCrCf(WebSocketConstant.ResponseLocationLine, session.UriScheme, session.Host, session.Path);
var subProtocol = session.GetAvailableSubProtocol(session.Items.GetValue<string>(WebSocketConstant.SecWebSocketProtocol, string.Empty));
if (!string.IsNullOrEmpty(subProtocol))
responseBuilder.AppendFormatWithCrCf(WebSocketConstant.ResponseProtocolLine, subProtocol);
responseBuilder.AppendWithCrCf();
byte[] data = Encoding.UTF8.GetBytes(responseBuilder.ToString());
session.SendRawData(data, 0, data.Length);
//Encrypt message
byte[] secret = GetResponseSecurityKey(secKey1, secKey2, secKey3);
session.SendRawData(secret, 0, secret.Length);
dataFrameReader = new WebSocketDataReceiveFilter(previousFilter);
return true;
}
示例3: SendHandshake
public override void SendHandshake(WebSocket websocket)
{
string secKey1 = Encoding.UTF8.GetString(GenerateSecKey());
string secKey2 = Encoding.UTF8.GetString(GenerateSecKey());
byte[] secKey3 = GenerateSecKey(8);
m_ExpectedChallenge = GetResponseSecurityKey(secKey1, secKey2, secKey3);
var handshakeBuilder = new StringBuilder();
#if SILVERLIGHT
handshakeBuilder.AppendFormatWithCrCf("GET {0} HTTP/1.1", websocket.TargetUri.GetPathAndQuery());
#else
handshakeBuilder.AppendFormatWithCrCf("GET {0} HTTP/1.1", websocket.TargetUri.PathAndQuery);
#endif
handshakeBuilder.AppendWithCrCf("Upgrade: WebSocket");
handshakeBuilder.AppendWithCrCf("Connection: Upgrade");
handshakeBuilder.Append("Sec-WebSocket-Key1: ");
handshakeBuilder.AppendWithCrCf(secKey1);
handshakeBuilder.Append("Sec-WebSocket-Key2: ");
handshakeBuilder.AppendWithCrCf(secKey2);
handshakeBuilder.Append("Host: ");
handshakeBuilder.AppendWithCrCf(websocket.TargetUri.Host);
handshakeBuilder.Append("Origin: ");
handshakeBuilder.AppendWithCrCf(string.IsNullOrEmpty(websocket.Origin) ? websocket.TargetUri.Host : websocket.Origin);
if (!string.IsNullOrEmpty(websocket.SubProtocol))
{
handshakeBuilder.Append("Sec-WebSocket-Protocol: ");
handshakeBuilder.AppendWithCrCf(websocket.SubProtocol);
}
var cookies = websocket.Cookies;
if (cookies != null && cookies.Count > 0)
{
string[] cookiePairs = new string[cookies.Count];
for (int i = 0; i < cookies.Count; i++)
{
var item = cookies[i];
cookiePairs[i] = item.Key + "=" + Uri.EscapeUriString(item.Value);
}
handshakeBuilder.Append("Cookie: ");
handshakeBuilder.AppendWithCrCf(string.Join(";", cookiePairs));
}
if (websocket.CustomHeaderItems != null)
{
for (var i = 0; i < websocket.CustomHeaderItems.Count; i++)
{
var item = websocket.CustomHeaderItems[i];
handshakeBuilder.AppendFormatWithCrCf(HeaderItemFormat, item.Key, item.Value);
}
}
handshakeBuilder.AppendWithCrCf();
handshakeBuilder.Append(Encoding.UTF8.GetString(secKey3, 0, secKey3.Length));
byte[] handshakeBuffer = Encoding.UTF8.GetBytes(handshakeBuilder.ToString());
websocket.Client.Send(handshakeBuffer, 0, handshakeBuffer.Length);
}
示例4: CreateOpenningHandshakeBadRequestResponse
internal static byte[] CreateOpenningHandshakeBadRequestResponse(AsyncWebSocketSession session)
{
var sb = new StringBuilder();
// HTTP/1.1 400 Bad Request
sb.AppendFormatWithCrCf("HTTP/{0} {1} {2}",
Consts.HttpVersion,
(int)HttpStatusCode.BadRequest,
@"Bad Request");
// Upgrade: websocket
sb.AppendFormatWithCrCf(Consts.HeaderLineFormat, HttpKnownHeaderNames.Upgrade, Consts.WebSocketUpgradeToken);
// Connection: Upgrade
sb.AppendFormatWithCrCf(Consts.HeaderLineFormat, HttpKnownHeaderNames.Connection, Consts.WebSocketConnectionToken);
// Sec-WebSocket-Version: 13
sb.AppendFormatWithCrCf(Consts.HeaderLineFormat, HttpKnownHeaderNames.SecWebSocketVersion, Consts.WebSocketVersion);
sb.AppendWithCrCf();
var response = sb.ToString();
#if DEBUG
_log.DebugFormat("[{0}]{1}{2}", session.RemoteEndPoint, Environment.NewLine, response);
#endif
return Encoding.UTF8.GetBytes(response);
}
示例5: CreateOpenningHandshakeResponse
internal static byte[] CreateOpenningHandshakeResponse(AsyncWebSocketSession session, string secWebSocketKey)
{
var sb = new StringBuilder();
// A Status-Line with a 101 response code as per RFC 2616
// [RFC2616]. Such a response could look like "HTTP/1.1 101 Switching Protocols".
sb.AppendFormatWithCrCf("HTTP/{0} {1} {2}",
Consts.HttpVersion,
(int)HttpStatusCode.SwitchingProtocols,
@"Switching Protocols");
// An |Upgrade| header field with value "websocket" as per RFC2616 [RFC2616].
sb.AppendFormatWithCrCf(Consts.HeaderLineFormat, HttpKnownHeaderNames.Upgrade, Consts.WebSocketUpgradeToken);
// A |Connection| header field with value "Upgrade".
sb.AppendFormatWithCrCf(Consts.HeaderLineFormat, HttpKnownHeaderNames.Connection, Consts.WebSocketConnectionToken);
// A |Sec-WebSocket-Accept| header field. The value of this
// header field is constructed by concatenating /key/, defined
// above in step 4 in Section 4.2.2, with the string "258EAFA5-
// E914-47DA-95CA-C5AB0DC85B11", taking the SHA-1 hash of this
// concatenated value to obtain a 20-byte value and base64-
// encoding (see Section 4 of [RFC4648]) this 20-byte hash.
var secWebSocketAccept = GetSecWebSocketAcceptString(secWebSocketKey);
sb.AppendFormatWithCrCf(Consts.HeaderLineFormat, HttpKnownHeaderNames.SecWebSocketAccept, secWebSocketAccept);
// Optionally, a |Sec-WebSocket-Extensions| header field, with a
// value /extensions/ as defined in step 4 in Section 4.2.2. If
// multiple extensions are to be used, they can all be listed in
// a single |Sec-WebSocket-Extensions| header field or split
// between multiple instances of the |Sec-WebSocket-Extensions| header field.
// A server accepts one or more extensions by including a
// |Sec-WebSocket-Extensions| header field containing one or more
// extensions that were requested by the client. The interpretation of
// any extension parameters, and what constitutes a valid response by a
// server to a requested set of parameters by a client, will be defined
// by each such extension.
if (session.NegotiatedExtensions != null && session.NegotiatedExtensions.Any())
{
foreach (var extension in session.NegotiatedExtensions.Values)
{
var offer = extension.GetAgreedOffer();
sb.AppendFormatWithCrCf(Consts.HeaderLineFormat, HttpKnownHeaderNames.SecWebSocketExtensions, offer);
}
}
/**
// Optionally, a |Sec-WebSocket-Protocol| header field, with a
// value /subprotocol/ as defined in step 4 in Section 4.2.2.
//
// The client can request that the server use a specific subprotocol by
// including the |Sec-WebSocket-Protocol| field in its handshake. If it
// is specified, the server needs to include the same field and one of
// the selected subprotocol values in its response for the connection to
// be established.
//
// These subprotocol names should be registered as per Section 11.5. To
// avoid potential collisions, it is recommended to use names that
// contain the ASCII version of the domain name of the subprotocol's
// originator. For example, if Example Corporation were to create a
// Chat subprotocol to be implemented by many servers around the Web,
// they could name it "chat.example.com". If the Example Organization
// called their competing subprotocol "chat.example.org", then the two
// subprotocols could be implemented by servers simultaneously, with the
// server dynamically selecting which subprotocol to use based on the
// value sent by the client.
//
// Subprotocols can be versioned in backward-incompatible ways by
// changing the subprotocol name, e.g., going from
// "bookings.example.net" to "v2.bookings.example.net". These
// subprotocols would be considered completely separate by WebSocket
// clients. Backward-compatible versioning can be implemented by
// reusing the same subprotocol string but carefully designing the
// actual subprotocol to support this kind of extensibility.
*/
sb.AppendWithCrCf();
// HTTP/1.1 101 Switching Protocols
// Upgrade: websocket
// Connection: Upgrade
// Sec-WebSocket-Accept: 1tGBmA9p0DQDgmFll6P0/UcVS/E=
// Sec-WebSocket-Protocol: chat
var response = sb.ToString();
#if DEBUG
_log.DebugFormat("[{0}]{1}{2}", session.RemoteEndPoint, Environment.NewLine, response);
#endif
return Encoding.UTF8.GetBytes(response);
}
示例6: SendHandshake
public override void SendHandshake(WebSocket websocket)
{
#if !SILVERLIGHT
var secKey = Convert.ToBase64String(Encoding.ASCII.GetBytes(Guid.NewGuid().ToString().Substring(0, 16)));
string expectedAccept = Convert.ToBase64String(SHA1.Create().ComputeHash(Encoding.ASCII.GetBytes(secKey + m_Magic)));
#else
var secKey = Convert.ToBase64String(ASCIIEncoding.Instance.GetBytes(Guid.NewGuid().ToString().Substring(0, 16)));
string expectedAccept = Convert.ToBase64String(SHA1.Create().ComputeHash(ASCIIEncoding.Instance.GetBytes(secKey + m_Magic)));
#endif
websocket.Items[m_ExpectedAcceptKey] = expectedAccept;
var handshakeBuilder = new StringBuilder();
#if SILVERLIGHT
handshakeBuilder.AppendFormatWithCrCf("GET {0} HTTP/1.1", websocket.TargetUri.GetPathAndQuery());
#else
handshakeBuilder.AppendFormatWithCrCf("GET {0} HTTP/1.1", websocket.TargetUri.PathAndQuery);
#endif
handshakeBuilder.AppendWithCrCf("Upgrade: WebSocket");
handshakeBuilder.AppendWithCrCf("Connection: Upgrade");
handshakeBuilder.Append("Sec-WebSocket-Version: ");
handshakeBuilder.AppendWithCrCf(VersionTag);
handshakeBuilder.Append("Sec-WebSocket-Key: ");
handshakeBuilder.AppendWithCrCf(secKey);
handshakeBuilder.Append("Host: ");
handshakeBuilder.AppendWithCrCf(websocket.HandshakeHost);
handshakeBuilder.Append("Origin: ");
handshakeBuilder.AppendWithCrCf(string.IsNullOrEmpty(websocket.Origin) ? websocket.TargetUri.Host : websocket.Origin);
if (!string.IsNullOrEmpty(websocket.SubProtocol))
{
handshakeBuilder.Append("Sec-WebSocket-Protocol: ");
handshakeBuilder.AppendWithCrCf(websocket.SubProtocol);
}
var cookies = websocket.Cookies;
if (cookies != null && cookies.Count > 0)
{
string[] cookiePairs = new string[cookies.Count];
for (int i = 0; i < cookies.Count; i++)
{
var item = cookies[i];
cookiePairs[i] = item.Key + "=" + Uri.EscapeUriString(item.Value);
}
handshakeBuilder.Append("Cookie: ");
handshakeBuilder.AppendWithCrCf(string.Join(";", cookiePairs));
}
if (websocket.CustomHeaderItems != null)
{
for (var i = 0; i < websocket.CustomHeaderItems.Count; i++)
{
var item = websocket.CustomHeaderItems[i];
handshakeBuilder.AppendFormatWithCrCf(HeaderItemFormat, item.Key, item.Value);
}
}
handshakeBuilder.AppendWithCrCf();
byte[] handshakeBuffer = Encoding.UTF8.GetBytes(handshakeBuilder.ToString());
websocket.Client.Send(handshakeBuffer, 0, handshakeBuffer.Length);
}
示例7: CreateOpenningHandshakeRequest
internal static byte[] CreateOpenningHandshakeRequest(AsyncWebSocketClient client, out string secWebSocketKey)
{
var sb = new StringBuilder();
// The handshake MUST be a valid HTTP request as specified by [RFC2616].
// The method of the request MUST be GET, and the HTTP version MUST be at least 1.1.
// For example, if the WebSocket URI is "ws://example.com/chat",
// the first line sent should be "GET /chat HTTP/1.1".
sb.AppendFormatWithCrCf("GET {0} HTTP/{1}",
!string.IsNullOrEmpty(client.Uri.PathAndQuery) ? client.Uri.PathAndQuery : "/",
Consts.HttpVersion);
// The request MUST contain a |Host| header field whose value
// contains /host/ plus optionally ":" followed by /port/ (when not
// using the default port).
sb.AppendFormatWithCrCf(Consts.HeaderLineFormat, HttpKnownHeaderNames.Host, client.Uri.Host);
// The request MUST contain an |Upgrade| header field whose value
// MUST include the "websocket" keyword.
sb.AppendFormatWithCrCf(Consts.HeaderLineFormat, HttpKnownHeaderNames.Upgrade, Consts.WebSocketUpgradeToken);
// The request MUST contain a |Connection| header field whose value
// MUST include the "Upgrade" token.
sb.AppendFormatWithCrCf(Consts.HeaderLineFormat, HttpKnownHeaderNames.Connection, Consts.WebSocketConnectionToken);
// The request MUST include a header field with the name
// |Sec-WebSocket-Key|. The value of this header field MUST be a
// nonce consisting of a randomly selected 16-byte value that has
// been base64-encoded (see Section 4 of [RFC4648]). The nonce
// MUST be selected randomly for each connection.
secWebSocketKey = Convert.ToBase64String(Encoding.ASCII.GetBytes(Guid.NewGuid().ToString().Substring(0, 16)));
sb.AppendFormatWithCrCf(Consts.HeaderLineFormat, HttpKnownHeaderNames.SecWebSocketKey, secWebSocketKey);
// The request MUST include a header field with the name
// |Sec-WebSocket-Version|. The value of this header field MUST be 13.
sb.AppendFormatWithCrCf(Consts.HeaderLineFormat, HttpKnownHeaderNames.SecWebSocketVersion, Consts.WebSocketVersion);
// The request MAY include a header field with the name
// |Sec-WebSocket-Extensions|. If present, this value indicates
// the protocol-level extension(s) the client wishes to speak. The
// interpretation and format of this header field is described in Section 9.1.
if (client.OfferedExtensions != null && client.OfferedExtensions.Any())
{
foreach (var extension in client.OfferedExtensions)
{
sb.AppendFormatWithCrCf(Consts.HeaderLineFormat, HttpKnownHeaderNames.SecWebSocketExtensions, extension.ExtensionNegotiationOffer);
}
}
// The request MAY include a header field with the name
// |Sec-WebSocket-Protocol|. If present, this value indicates one
// or more comma-separated subprotocol the client wishes to speak,
// ordered by preference. The elements that comprise this value
// MUST be non-empty strings with characters in the range U+0021 to
// U+007E not including separator characters as defined in
// [RFC2616] and MUST all be unique strings. The ABNF for the
// value of this header field is 1#token, where the definitions of
// constructs and rules are as given in [RFC2616].
if (client.RequestedSubProtocols != null && client.RequestedSubProtocols.Any())
{
foreach (var description in client.RequestedSubProtocols)
{
sb.AppendFormatWithCrCf(Consts.HeaderLineFormat, HttpKnownHeaderNames.SecWebSocketProtocol, description.RequestedSubProtocol);
}
}
// The request MUST include a header field with the name |Origin|
// [RFC6454] if the request is coming from a browser client. If
// the connection is from a non-browser client, the request MAY
// include this header field if the semantics of that client match
// the use-case described here for browser clients. The value of
// this header field is the ASCII serialization of origin of the
// context in which the code establishing the connection is
// running. See [RFC6454] for the details of how this header field
// value is constructed.
// The request MAY include any other header fields, for example,
// cookies [RFC6265] and/or authentication-related header fields
// such as the |Authorization| header field [RFC2616], which are
// processed according to documents that define them.
sb.AppendWithCrCf();
// GET /chat HTTP/1.1
// Host: server.example.com
// Upgrade: websocket
// Connection: Upgrade
// Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
// Sec-WebSocket-Protocol: chat, superchat
// Sec-WebSocket-Version: 13
// Origin: http://example.com
var request = sb.ToString();
#if DEBUG
_log.DebugFormat("[{0}]{1}{2}", client.RemoteEndPoint, Environment.NewLine, request);
#endif
return Encoding.UTF8.GetBytes(request);
}
示例8: BuildHandeshakeContext
public static HandshakeContext BuildHandeshakeContext(
string host,
string path,
string key = null,
string protocol = null,
string version = null,
string extensions = null,
string origin = null,
IEnumerable<KeyValuePair<string, string>> cookies = null)
{
if (string.IsNullOrEmpty(host))
throw new ArgumentNullException("host");
if (string.IsNullOrEmpty(path))
throw new ArgumentNullException("path");
var sb = new StringBuilder();
if (string.IsNullOrEmpty(key))
key = Convert.ToBase64String(Encoding.ASCII.GetBytes(Guid.NewGuid().ToString().Substring(0, 16)));
sb.AppendFormatWithCrCf("GET {0} HTTP/1.1", path);
sb.AppendFormatWithCrCf("Host: {0}", host);
sb.AppendWithCrCf("Upgrade: websocket");
sb.AppendWithCrCf("Connection: Upgrade");
// In addition to Upgrade headers, the client sends a Sec-WebSocket-Key header
// containing base64-encoded random bytes, and the server replies with a hash of the key
// in the Sec-WebSocket-Accept header. This is intended to prevent a caching proxy
// from re-sending a previous WebSocket conversation, and does not provide any authentication,
// privacy or integrity. The hashing function appends the
// fixed string 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 (a GUID) to the value
// from Sec-WebSocket-Key header (which is not decoded from base64),
// applies the SHA-1 hashing function, and encodes the result using base64.
sb.AppendFormatWithCrCf("Sec-WebSocket-Key: {0}", key);
// The |Sec-WebSocket-Version| header field in the client's
// handshake includes the version of the WebSocket Protocol with
// which the client is attempting to communicate. If this
// version does not match a version understood by the server, the
// server MUST abort the WebSocket handshake described in this
// section and instead send an appropriate HTTP error code(such
// as 426 Upgrade Required) and a |Sec-WebSocket-Version| header
// field indicating the version(s)the server is capable of understanding.
if (!string.IsNullOrEmpty(version))
sb.AppendFormatWithCrCf("Sec-WebSocket-Version: {0}", version);
else
sb.AppendFormatWithCrCf("Sec-WebSocket-Version: {0}", 13);
// Optionally
// The |Sec-WebSocket-Protocol| request-header field can be
// used to indicate what subprotocols(application - level protocols
// layered over the WebSocket Protocol) are acceptable to the client.
if (!string.IsNullOrEmpty(protocol))
sb.AppendFormatWithCrCf("Sec-WebSocket-Protocol: {0}", protocol);
// Optionally
// A (possibly empty) list representing the protocol-level
// extensions the server is ready to use.
if (!string.IsNullOrEmpty(extensions))
sb.AppendFormatWithCrCf("Sec-WebSocket-Extensions: {0}", extensions);
// Optionally
// The |Origin| header field is used to protect against
// unauthorized cross-origin use of a WebSocket server by scripts using
// the WebSocket API in a web browser.
// This header field is sent by browser clients; for non-browser clients,
// this header field may be sent if it makes sense in the context of those clients.
if (!string.IsNullOrEmpty(origin))
sb.AppendFormatWithCrCf("Origin: {0}", origin);
if (cookies != null && cookies.Any())
{
string[] pairs = new string[cookies.Count()];
for (int i = 0; i < cookies.Count(); i++)
{
var item = cookies.ElementAt(i);
pairs[i] = item.Key + "=" + Uri.EscapeUriString(item.Value);
}
sb.AppendFormatWithCrCf("Cookie: {0}", string.Join(";", pairs));
}
sb.AppendWithCrCf();
// GET /chat HTTP/1.1
// Host: server.example.com
// Upgrade: websocket
// Connection: Upgrade
// Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
// Sec-WebSocket-Protocol: chat, superchat
// Sec-WebSocket-Version: 13
// Origin: http://example.com
var message = sb.ToString();
var requestBuffer = Encoding.UTF8.GetBytes(message);
var context = new HandshakeContext()
{
RequestBuffer = requestBuffer,
//.........这里部分代码省略.........