diff --git a/WebSockets.Client/System.Net.WebSockets.Client.nfproj b/WebSockets.Client/System.Net.WebSockets.Client.nfproj
index b42f938..4cc0112 100644
--- a/WebSockets.Client/System.Net.WebSockets.Client.nfproj
+++ b/WebSockets.Client/System.Net.WebSockets.Client.nfproj
@@ -38,6 +38,9 @@
ClientWebSocket\ClientWebSocketOptions.cs
+
+
+ ClientWebSocket\ClientWebSocketHeaders.cs
MessageReceivedEventArgs.cs
diff --git a/WebSockets/ClientWebSocket/ClientWebSocket.cs b/WebSockets/ClientWebSocket/ClientWebSocket.cs
index 3c6eb24..d20080f 100644
--- a/WebSockets/ClientWebSocket/ClientWebSocket.cs
+++ b/WebSockets/ClientWebSocket/ClientWebSocket.cs
@@ -111,7 +111,8 @@ public ClientWebSocket(ClientWebSocketOptions options = null) : base(options)
/// Connect to a WebSocket server.
///
/// The URI of the WebSocket server to connect to.
- public void Connect(string uri)
+ /// Optional for setting custom headers.
+ public void Connect(string uri, ClientWebSocketHeaders headers = null)
{
State = WebSocketFrame.WebSocketState.Connecting;
@@ -195,7 +196,7 @@ public void Connect(string uri)
_networkStream = new NetworkStream(_tcpSocket, true);
}
- WebSocketClientConnect(ep, prefix, Host);
+ WebSocketClientConnect(ep, prefix, Host, headers);
}
catch (SocketException ex)
{
@@ -212,15 +213,27 @@ private void WebSocket_ConnectionClosed(object sender, EventArgs e)
_tcpSocket.Close();
}
- private void WebSocketClientConnect(IPEndPoint remoteEndPoint, string prefix = "/", string host = null)
+ private void WebSocketClientConnect(IPEndPoint remoteEndPoint, string prefix = "/", string host = null, ClientWebSocketHeaders customHeaders = null)
{
+ string customHeaderString = string.Empty;
+ if (customHeaders != null)
+ {
+ var headerKeys = customHeaders.Keys;
+ foreach (string key in headerKeys)
+ {
+ if (!string.IsNullOrEmpty(key))
+ {
+ customHeaderString += $"{key}: {customHeaders[key]}\r\n";
+ }
+ }
+ }
if (prefix[0] != '/') throw new Exception("websocket prefix has to start with '/'");
byte[] keyBuf = new byte[16];
new Random().NextBytes(keyBuf);
string swk = Convert.ToBase64String(keyBuf);
- byte[] sendBuffer = Encoding.UTF8.GetBytes($"GET {prefix} HTTP/1.1\r\nHost: {(host != null ? host : remoteEndPoint.Address.ToString())}\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: {swk}\r\nSec-WebSocket-Version: 13\r\n\r\n");
+ byte[] sendBuffer = Encoding.UTF8.GetBytes($"GET {prefix} HTTP/1.1\r\nHost: {(host != null ? host : remoteEndPoint.Address.ToString())}\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: {swk}\r\nSec-WebSocket-Version: 13\r\n{customHeaderString}\r\n");
_networkStream.Write(sendBuffer, 0, sendBuffer.Length);
string beginHeader = ($"HTTP/1.1 101".ToLower());
diff --git a/WebSockets/ClientWebSocket/ClientWebSocketHeaders.cs b/WebSockets/ClientWebSocket/ClientWebSocketHeaders.cs
new file mode 100644
index 0000000..6c2f747
--- /dev/null
+++ b/WebSockets/ClientWebSocket/ClientWebSocketHeaders.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Collections;
+using System.Text;
+
+namespace System.Net.WebSockets
+{
+ ///
+ /// A Dictionary to store custom Http Headers to use with the ClientWebsocket
+ ///
+ public class ClientWebSocketHeaders
+ {
+ private Hashtable _headers = new Hashtable();
+
+ ///
+ /// Gets the number of headers.
+ ///
+ public int Count { get { return _headers.Count; } }
+
+ ///
+ /// Gets all header keys.
+ ///
+ public string[] Keys { get { return GetKeys(); } }
+
+ ///
+ /// Gets all header values.
+ ///
+ public string[] Values { get { return GetValues(); } }
+
+ ///
+ /// Gets a value header or Sets a header value
+ ///
+ public string this[string key]
+ {
+ get
+ {
+ return _headers[key] as string;
+ }
+ set
+ {
+
+ _headers[key] = value;
+
+ }
+ }
+
+ ///
+ /// Removes a header from the dictionary
+ ///
+ public void Remove(string value)
+ {
+ _headers.Remove(value);
+
+ }
+
+ private string[] GetKeys()
+ {
+ var keys = _headers.Keys;
+ string[] returnkeys = new string[keys.Count];
+
+ int i = 0;
+ foreach (object key in keys)
+ {
+ returnkeys[i] = key as string;
+ i++;
+ }
+
+ return returnkeys;
+ }
+
+ private string[] GetValues()
+ {
+ var values = _headers.Values;
+ string[] returnkeys = new string[values.Count];
+
+ int i = 0;
+ foreach (object value in values)
+ {
+ returnkeys[i] = value as string;
+ i++;
+ }
+
+ return returnkeys;
+ }
+ }
+}
diff --git a/WebSockets/System.Net.WebSockets.nfproj b/WebSockets/System.Net.WebSockets.nfproj
index 8d38d06..7a6ccfb 100644
--- a/WebSockets/System.Net.WebSockets.nfproj
+++ b/WebSockets/System.Net.WebSockets.nfproj
@@ -33,6 +33,7 @@
+
diff --git a/WebSockets/WebSocket.cs b/WebSockets/WebSocket.cs
index c9400db..eca396c 100644
--- a/WebSockets/WebSocket.cs
+++ b/WebSockets/WebSocket.cs
@@ -302,9 +302,15 @@ internal void HardClose()
ConnectionClosed?.Invoke(this, new EventArgs());
//Let the tcp socket linger for a second so it can try and send all data out before final close.
- _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, 1);
-
- _socket.Close();
+ try
+ {
+ _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, 1);
+ _socket.Close();
+ }
+ catch (ObjectDisposedException e)
+ {
+ Debug.WriteLine("socket could not be closed properly because it was already disposed");
+ }
}
internal bool QueueMessageToSend(SendMessageFrame frame)