-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add OnSocketAvailableAsync Hook #647
Conversation
@@ -1,6 +1,6 @@ | |||
namespace NATS.Client.Core.Internal; | |||
|
|||
internal interface ISocketConnection : IAsyncDisposable | |||
public interface ISocketConnection : IAsyncDisposable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we need to make it public we should move the file out of internal
edit: also does this really need to be public?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, if we want to use it in public Func<ISocketConnection, ValueTask<ISocketConnection>>
. Will move it.
@@ -34,6 +34,7 @@ public partial class NatsConnection : INatsConnection | |||
/// Hook before TCP connection open. | |||
/// </summary> | |||
public Func<(string Host, int Port), ValueTask<(string Host, int Port)>>? OnConnectingAsync; | |||
public Func<ISocketConnection, Task>? OnSocketAvailableAsync; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should pull this up to INatsConnection
as well. also can we return ValueTask
to be consistent?
thanks @johannespfeiffer looks very useful. can you think of a way to write a test? (I think websocket callbacks have a test might be helpful) |
23c9634
to
526f09a
Compare
1e30cea
to
2fa95e6
Compare
I will try to test this soon. Do you have an example setup or some kind of instructions to try it out in a real setup e.g. with a proxy like Squid or something? |
Yes, exactly like that. I used squid on a separate machine (just used the standard settings). Then on the machine running the nats-client I've added a firewall rule to only allow outgoing connections to the machine with the squid proxy. |
finally got around to this. sorry for the delay. here is a working example augmenting the example above: using System.Text;
using NATS.Client.Core;
var proxy = "localhost:3128";
var nats = "demo.nats.io:4222";
await using var connection = new NatsConnection(new NatsOpts
{
Url = proxy,
TlsOpts = new NatsTlsOpts { Mode = TlsMode.Disable },
});
// Must assign a delegate to OnSocketAvailableAsync before calling ConnectAsync or any other method
connection.OnSocketAvailableAsync = async socket =>
{
// Send CONNECT request to proxy
await socket.SendAsync(Encoding.ASCII.GetBytes($"CONNECT {nats} HTTP/1.1\r\nHost: {nats}\r\n\r\n"));
// Validate proxy response
var buffer = new byte[4096];
var read = await socket.ReceiveAsync(buffer);
var response = Encoding.ASCII.GetString(buffer, 0, read);
if (!response.Contains("200 Connection established"))
{
throw new Exception($"Proxy connection failed. Response: {response}");
}
return socket;
};
// Establish connection to NATS server through the proxy
await connection.ConnectAsync();
Console.WriteLine($"Connected to server {connection.ServerInfo?.Name}");
// Work with the connection as usual
var rtt = await connection.PingAsync();
Console.WriteLine($"RTT {rtt}"); If you install a local Squid proxy server to forward traffic to the NATS server make sure to comment out the following line in the Squid configuration file:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM thanks @johannespfeiffer
* Add OnSocketAvailableAsync Hook (#647) * Refactor exception handling in NatsException (#677) * Fixed an exception which happens when PutAsync is used more than once and activity logging is enabled in main project (#675) * open Header.Writer class and create GetBytesLength method (#674) * Fix date time serialization to use ISO8601 (#664)
* Add OnSocketAvailableAsync Hook (#647) * Refactor exception handling in NatsException (#677) * Fixed an exception which happens when PutAsync is used more than once and activity logging is enabled in main project (#675) * open Header.Writer class and create GetBytesLength method (#674) * Fix date time serialization to use ISO8601 (#664)
Motivation
This change adds the
OnSocketAvailableAsync
hook, allowing users to perform actions on the socket once it becomes available. This is particularly useful for scenarios where an HTTP proxy is required to connect to a NATS server.Key Change
This hook enables users to interact with the socket directly, allowing custom actions such as sending an HTTP CONNECT request to establish a tunnel through a proxy.
Example Usage