今早上班路上接到了一個朋友的微信信息,問我對WebSocket 是否熟悉,一楞,印象之中沒有用過這個類....來到公司后,得空問了一下度娘,原來這是一個隨着HTML5推出的一種新協議,意義在於能實現瀏覽器與服務器全雙工通信(full-duplex)。度娘對此的解釋是:
internal class WinHttpWebSocket : WebSocket
{
.....
public async Task ConnectAsync(Uri uri, CancellationToken cancellationToken, ClientWebSocketOptions options)
{
.....
_operation.SessionHandle = InitializeWinHttp(options);
_operation.ConnectionHandle = Interop.WinHttp.WinHttpConnectWithCallback(
_operation.SessionHandle,
uri.IdnHost,
(ushort)uri.Port,
0);
ThrowOnInvalidHandle(_operation.ConnectionHandle);
bool secureConnection = uri.Scheme == UriScheme.Https || uri.Scheme == UriScheme.Wss;
_operation.RequestHandle = Interop.WinHttp.WinHttpOpenRequestWithCallback(
_operation.ConnectionHandle,
"GET",
uri.PathAndQuery,
null,
Interop.WinHttp.WINHTTP_NO_REFERER,
null,
secureConnection ? Interop.WinHttp.WINHTTP_FLAG_SECURE : 0);
ThrowOnInvalidHandle(_operation.RequestHandle);
_operation.IncrementHandlesOpenWithCallback();
.....
}
......
}
namespace System.Net.Sockets
{
public partial class Socket : IDisposable
{
.......
public void Connect(EndPoint remoteEP)
{
......
EndPoint endPointSnapshot = remoteEP;
Internals.SocketAddress socketAddress = CheckCacheRemote(ref endPointSnapshot, true);
if (!Blocking)
{
_nonBlockingConnectRightEndPoint = endPointSnapshot;
_nonBlockingConnectInProgress = true;
}
DoConnect(endPointSnapshot, socketAddress);
}
private void DoConnect(EndPoint endPointSnapshot, Internals.SocketAddress socketAddress)
{
.......
SocketError errorCode = SocketPal.Connect(_handle, socketAddress.Buffer, socketAddress.Size);
......
}
......
}
}
namespace System.Net.Sockets
{
internal static class SocketPal
{
.......
public static SocketError Connect(SafeCloseSocket handle, byte[] peerAddress, int peerAddressLen)
{
SocketError errorCode = Interop.Winsock.WSAConnect(
handle.DangerousGetHandle(),
peerAddress,
peerAddressLen,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero);
return errorCode == SocketError.SocketError ? GetLastSocketError() : SocketError.Success;
}
.......
}
}
由上面代碼可見,
(1)WebSocket最終調用了WinHTTP 的api,WinHTTP的全稱是Microsoft Windows HTTP Services, 它提供給開發者一個HTTP客戶端應用程序接口(API), 通過這種API借助HTTP協議給其他的HTTP服務器發送請求.關於WinHTTP 的詳細API,請自行查詢資料,網上一大把,這里不再累贅copy。由此可以驗證了WebSocket是基於HTTP請求的,從調用的WinHTTPAPI方法名稱可以得知,都是帶有回調的方法,也正驗證了WebSocket的雙工通信的特點。
(2)Socket最終是調用了windows的Winsock接口,Winsock是Windows下的網絡編程接口,它是由Unix下的BSD Socket發展而來,是一個與網絡協議無關的編程接口。具體信息請自行查詢網上資源。
因此,我個人覺得,WebSocket和Socket在技術上並沒有太多關系,底層原理也是不同的,WebSocket 是為了滿足基於 Web 的日益增長的實時通信需求而產生的,可以在一些實時通信時,代替采用 HTTP 協議不斷發送請求的通用的方式,以達到帶寬浪費和服務器 CPU 的消耗,更重要的是它是一種協議,而Socket是應用層與TCP/IP協議族通信的中間軟件抽象層,它是一組接口,並不是協議,WebSocket不能等同Socket,也不是Socket的演化,更不能代替Socket。
