ecorm / cppwamp

C++ client library for the WAMP protocol.
Boost Software License 1.0
35 stars 9 forks source link

TCP socket options #63

Closed taion closed 9 years ago

taion commented 9 years ago

I can't find a way to set TCP socket options on TcpConnector (e.g. for turning off Nagle). Am I looking in the wrong place, or is this not currently possible?

ecorm commented 9 years ago

This is currently not possible. I had overlooked the possibility of passing socket options. I will try to rectify this soon.

In the meantime, you could temporarily hack internal::AsioTransport::create to set your socket options there using asio::ip::tcp::socket::set_option.

If you need to set options before the socket connects, you could also hack internal::TcpOpener::connect.

ecorm commented 9 years ago

Other than UDP multicast, are there any use cases where someone would need to set socket options after the socket has connected? It seems to me that most of the time, you'd want to set the options beforehand.

The current connection API has the following goals:

These goals led to the current design where Session needs to know all the connection details beforehand. Unfortunately this design makes it difficult for the user to arbitrarily set socket options at any given point in time.

The problem is not insurmountable, and I already have ideas bouncing in my head on how to fix all this.

taion commented 9 years ago

I've blocked out all memory of UDP multicast, sorry, but is this just for joining multicast groups? I think even in that case, it should be fine to specify which groups you want at the time that you set up the Connector.

Although I think you'd need to do a lot of other work anyway to get WAMP to work reasonably on an unreliable transport, so I'm inclined to think that's just a non-issue for now.

For my purposes I'd be pretty happy if options were exposed at construction time of the Connector.

ecorm commented 9 years ago

I've blocked out all memory of UDP multicast, sorry, but is this just for joining multicast groups?

Yes, joining a multicast group is done via setsocketopt. I have no plans on implementing a UDP-based transport. I was just trying to see if there are any use cases where you'd need to set a TCP socket option after the socket has connected.

Although I think you'd need to do a lot of other work anyway to get WAMP to work reasonably on an unreliable transport, so I'm inclined to think that's just a non-issue for now.

I agree that for UDP, you'd need a whole other Connector subsclass, as well as a dedicated Transport implementation.

For my purposes I'd be pretty happy if options were exposed at construction time of the Connector.

I was planning on adding a TcpConnector::setOption member, and you could pass in any of Boost.Asio's socket options (shown under "Socket Options" in the Boost.Asio reference).

So the usage would look like:

auto tcp = TcpConnector::create(...);
tcp.setOption(boost::asio::ip::tcp::no_delay(true)); // Disables Nagle algorithm
tcp.setOption( <another option> );
auto session = Session::create(tcp);
session.connect(handler);

The connector would remember these options, and would apply them every time a Session connects using that Connector.

taion commented 9 years ago

I feel like it'd be cleaner to pass this into the constructor, so it's really clear that these options are immutable, but I don't know how that looks implementation-wise, given the way set_option is written with its template.

ecorm commented 9 years ago

You make a good point about making it clear that the options are immutable. If setting options were done via the constructor, I think the constructor overload would end up being a variadic template member function, with a template parameter pack for the one or more SettableSocketOption objects that are passed in.

I'm pretty confident I can make it work with the constructor.

ecorm commented 9 years ago

I'm currently working on this right now. @taion , can you think of an easy way to know if an option has taken effect, without resorting to a sniffer?

taion commented 9 years ago

I don't think I understand Asio well enough to answer that question. Is set_option not guaranteed to set the option if it doesn't set an error code? Or are there options you can call set_option on that you can't call get_option on?

ecorm commented 9 years ago

I was thinking more of a "black box" way of checking it. I found an easy solution here: http://serverfault.com/questions/283581/finding-the-so-sndbuf-of-a-running-process

taion commented 9 years ago

Oh, you meant examining the process from the outside. I misunderstood, sorry.