Skip to content

Commit affdda9

Browse files
authored
WebSocket: Expose transport specific options (#278)
1 parent b35de23 commit affdda9

File tree

4 files changed

+346
-0
lines changed

4 files changed

+346
-0
lines changed

Source/HiveMQtt/Client/HiveMQClientOptionsBuilder.cs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
*/
1616
namespace HiveMQtt.Client;
1717

18+
using System;
19+
using System.Collections.Generic;
20+
using System.Net;
1821
using System.Security;
1922
using System.Security.Cryptography.X509Certificates;
2023
using HiveMQtt.Client.Options;
@@ -91,6 +94,81 @@ public HiveMQClientOptionsBuilder WithWebSocketServer(string webSocketServer)
9194
return this;
9295
}
9396

97+
/// <summary>
98+
/// Sets the WebSocket keep-alive interval.
99+
/// <para>
100+
/// This specifies the interval at which the WebSocket client will send keep-alive pings to the server
101+
/// to maintain the connection. If not set, the default WebSocket keep-alive behavior is used.
102+
/// </para>
103+
/// <para>
104+
/// This option is only applicable when using WebSocket transport (ws:// or wss://).
105+
/// </para>
106+
/// </summary>
107+
/// <param name="keepAliveInterval">The keep-alive interval.</param>
108+
/// <returns>The HiveMQClientOptionsBuilder instance.</returns>
109+
public HiveMQClientOptionsBuilder WithWebSocketKeepAliveInterval(TimeSpan keepAliveInterval)
110+
{
111+
this.options.WebSocketKeepAliveInterval = keepAliveInterval;
112+
return this;
113+
}
114+
115+
/// <summary>
116+
/// Sets custom HTTP headers to be sent during the WebSocket handshake.
117+
/// <para>
118+
/// This allows you to add custom headers such as Authorization, X-API-Key, or any other
119+
/// custom headers required by your WebSocket server. Headers are sent during the initial WebSocket
120+
/// connection handshake.
121+
/// </para>
122+
/// <para>
123+
/// This option is only applicable when using WebSocket transport (ws:// or wss://).
124+
/// </para>
125+
/// </summary>
126+
/// <param name="headers">A dictionary of header names and values.</param>
127+
/// <returns>The HiveMQClientOptionsBuilder instance.</returns>
128+
public HiveMQClientOptionsBuilder WithWebSocketRequestHeaders(Dictionary<string, string> headers)
129+
{
130+
this.options.WebSocketRequestHeaders = headers;
131+
return this;
132+
}
133+
134+
/// <summary>
135+
/// Adds a custom HTTP header to be sent during the WebSocket handshake.
136+
/// <para>
137+
/// This is a convenience method for adding a single header. For multiple headers, use
138+
/// <see cref="WithWebSocketRequestHeaders(Dictionary{string, string})"/>.
139+
/// </para>
140+
/// <para>
141+
/// This option is only applicable when using WebSocket transport (ws:// or wss://).
142+
/// </para>
143+
/// </summary>
144+
/// <param name="name">The header name.</param>
145+
/// <param name="value">The header value.</param>
146+
/// <returns>The HiveMQClientOptionsBuilder instance.</returns>
147+
public HiveMQClientOptionsBuilder WithWebSocketRequestHeader(string name, string value)
148+
{
149+
this.options.WebSocketRequestHeaders ??= new Dictionary<string, string>();
150+
this.options.WebSocketRequestHeaders[name] = value;
151+
return this;
152+
}
153+
154+
/// <summary>
155+
/// Sets the proxy configuration for WebSocket connections.
156+
/// <para>
157+
/// This allows you to configure a proxy server for WebSocket connections. If not set, the system's
158+
/// default proxy settings are used.
159+
/// </para>
160+
/// <para>
161+
/// This option is only applicable when using WebSocket transport (ws:// or wss://).
162+
/// </para>
163+
/// </summary>
164+
/// <param name="proxy">The proxy configuration.</param>
165+
/// <returns>The HiveMQClientOptionsBuilder instance.</returns>
166+
public HiveMQClientOptionsBuilder WithWebSocketProxy(IWebProxy proxy)
167+
{
168+
this.options.WebSocketProxy = proxy;
169+
return this;
170+
}
171+
94172
/// <summary>
95173
/// Sets the port to connect to.
96174
/// <para>

Source/HiveMQtt/Client/Options/HiveMQClientOptions.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
namespace HiveMQtt.Client.Options;
1717

1818
using System;
19+
using System.Collections.Generic;
1920
using System.Linq;
21+
using System.Net;
2022
using System.Security;
2123
using System.Security.Cryptography.X509Certificates;
2224
using HiveMQtt.Client;
@@ -214,6 +216,59 @@ public HiveMQClientOptions()
214216
/// </summary>
215217
public bool AutomaticReconnect { get; set; }
216218

219+
/// <summary>
220+
/// Gets or sets the WebSocket keep-alive interval.
221+
/// <para>
222+
/// This specifies the interval at which the WebSocket client will send keep-alive pings to the server
223+
/// to maintain the connection. If not set, the default WebSocket keep-alive behavior is used.
224+
/// </para>
225+
/// <para>
226+
/// This option is only applicable when using WebSocket transport (ws:// or wss://).
227+
/// </para>
228+
/// </summary>
229+
public TimeSpan? WebSocketKeepAliveInterval { get; set; }
230+
231+
/// <summary>
232+
/// Gets or sets custom HTTP headers to be sent during the WebSocket handshake.
233+
/// <para>
234+
/// This dictionary allows you to add custom headers such as Authorization, X-API-Key, or any other
235+
/// custom headers required by your WebSocket server. Headers are sent during the initial WebSocket
236+
/// connection handshake.
237+
/// </para>
238+
/// <para>
239+
/// This option is only applicable when using WebSocket transport (ws:// or wss://).
240+
/// </para>
241+
/// <para>
242+
/// Example:
243+
/// <code>
244+
/// options.WebSocketRequestHeaders = new Dictionary&lt;string, string&gt;
245+
/// {
246+
/// { "Authorization", "Bearer token123" },
247+
/// { "X-API-Key", "api-key-value" }
248+
/// };
249+
/// </code>
250+
/// </para>
251+
/// </summary>
252+
public Dictionary<string, string>? WebSocketRequestHeaders { get; set; }
253+
254+
/// <summary>
255+
/// Gets or sets the proxy configuration for WebSocket connections.
256+
/// <para>
257+
/// This allows you to configure a proxy server for WebSocket connections. If not set, the system's
258+
/// default proxy settings are used.
259+
/// </para>
260+
/// <para>
261+
/// This option is only applicable when using WebSocket transport (ws:// or wss://).
262+
/// </para>
263+
/// <para>
264+
/// Example:
265+
/// <code>
266+
/// options.WebSocketProxy = new WebProxy("http://proxy.example.com:8080");
267+
/// </code>
268+
/// </para>
269+
/// </summary>
270+
public IWebProxy? WebSocketProxy { get; set; }
271+
217272
/// <summary>
218273
/// Generate a semi-random client identifier to be used in <c>Client</c> connections.
219274
/// hmqc#-pid-randomstring.

Source/HiveMQtt/Client/Transport/WebSocketTransport.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ public WebSocketTransport(HiveMQClientOptions options)
6464
throw new ArgumentException("Invalid WebSocket URI scheme");
6565
}
6666

67+
// Configure WebSocket-specific options
68+
this.ConfigureWebSocketOptions();
69+
6770
// Configure TLS options for secure WebSocket (wss://)
6871
if (uri.Scheme == "wss")
6972
{
@@ -114,6 +117,37 @@ private static bool ValidateWebSocketServerCertificate(
114117
return false;
115118
}
116119

120+
/// <summary>
121+
/// Configure WebSocket-specific options from HiveMQClientOptions.
122+
/// </summary>
123+
private void ConfigureWebSocketOptions()
124+
{
125+
// Configure keep-alive interval if specified
126+
if (this.Options.WebSocketKeepAliveInterval.HasValue)
127+
{
128+
this.Socket.Options.KeepAliveInterval = this.Options.WebSocketKeepAliveInterval.Value;
129+
Logger.Trace($"WebSocket keep-alive interval set to {this.Options.WebSocketKeepAliveInterval.Value}");
130+
}
131+
132+
// Configure custom request headers if specified
133+
if (this.Options.WebSocketRequestHeaders != null && this.Options.WebSocketRequestHeaders.Count > 0)
134+
{
135+
foreach (var header in this.Options.WebSocketRequestHeaders)
136+
{
137+
this.Socket.Options.SetRequestHeader(header.Key, header.Value);
138+
}
139+
140+
Logger.Trace($"Added {this.Options.WebSocketRequestHeaders.Count} custom header(s) for WebSocket connection");
141+
}
142+
143+
// Configure proxy if specified
144+
if (this.Options.WebSocketProxy != null)
145+
{
146+
this.Socket.Options.Proxy = this.Options.WebSocketProxy;
147+
Logger.Trace($"WebSocket proxy configured: {this.Options.WebSocketProxy}");
148+
}
149+
}
150+
117151
/// <summary>
118152
/// Configure TLS options for secure WebSocket connections.
119153
/// </summary>

0 commit comments

Comments
 (0)