Should I be using NIO? (x-platform client app + WebSockets)

I'm considering what to use for WebSocket-based networking in my project. The project is a P2P app, so primarily client-side but can also be run as a lightweight server. It needs to be cross-platform; my priority list is basically iOS, Mac, Linux desktop, Android, Windows (in descending order.)

  • SwiftNIO looks good! But I wonder if it's overkill, since I don't need high scalability. Is the complexity & code size worth it?
  • Apple's Network.framework is very nice, but not cross-platform.
  • Ditto NSURLSession (plus it only does WebSocket clients, not servers.)
  • There are a couple of independent WebSocket implementations on Github, but I haven't looked into them to see what networking libs they use; I'm guessing they use NSURLSession.

Thanks for any advice.

Not sure how you want to address the "cross platform" side on Linux, Android and Windows (for production)?
In Shrugs I use GitHub - tidwall/SwiftWebSocket: Fast Websockets in Swift for iOS and OSX, primarily because it is pre-NW. In a project I use the low level NW WebSocket stuff as well as URLSession WebSockets, both work well too.

as someone who generally does not like to depend on large networking frameworks, i would still strongly recommend using SwiftNIO. it is very well-partitioned dependency-wise, and that is really saying something because Apple tends to be really bad at this because they ship everything with the OS and they are rarely thinking about things like static linking. so in my mind SwiftNIO does not suffer from the giant framework problem a lot of libraries in the swift ecosystem have and you should absolutely consider depending on it.

i assume most people just layer on top of NIOWebSocket, at least that is what i do. i experimented in the past with stream-based abstractions but i always ended up going back to writing a normal channel handler for this kind of thing.

3 Likes

I'm not sure why you would use NIO on Darwin platforms. It just sits on top of NW anyways and WebSockets are already builtin.

i mostly use it on server linux (which i guess is close enough to the “desktop linux” target OP mentioned) and that is a non-Darwin platform.

i don’t know enough about building NIO on Darwin to say how much code it links there, but i assume if it is already part of the OS that is less of a problem?

No, NIO is not part of the system, you'd usually link to it statically.

1 Like

Not that I'm misunderstood, I think the NIO implementation is great, I just wouldn't use it on Darwin, which has it builtin.

I'm not sure why you would use NIO on Darwin platforms

To avoid having to have two implementations of networking in my app, basically. Makes it harder to test and opens up more room for behavioral differences between platforms that can lead to bugs.

3 Likes

I think either is fine, I would personally rather abstract on top of the two, but NIO isn't that big either.

Note that Windows support for NIO is not something that is currently available. AIUI, @lukasa's last suggestion that Windows support would likely need to be a custom loop implementation for Windows support rather than be part of the core implementation. This support is not currently high in my priority list and I'm not aware of anyone else working on it either.

2 Likes

Oh! I saw your post from earlier this year "Windows <3 NIO", and from skimming it I got the impression Windows was supported. Now I see it's a PR, and I guess it wasn't merged? Anyway, good to know.

Yes, the set of patches to enable it demonstrated it was possible, but they were never fully merged.

We thought the same and it didn't work for us. Speaking from past personal experience there's a huge and often underestimated maintenance and overall overhead when using cross platform approaches. E.g. you may end up with 10K lines of code and some convoluted system to build the app when using cross platform code vs some 3x300 LOC when using platform built-in libraries. The situation exaggerates when something doesn't work and you need to tweak something on the platform and it comes to debugging: platform A person would need to know language B, which is foreign to platform A – this translates into a smaller pool of candidates to choose from and higher wages, being a small company in our case that was a show stopper. YMMV.

1 Like

This is correct: in my view, trying to get NIOPosix to work on Windows is going to be excessively painful. NIO has a way to support multiple loop and channel implementations (which is what we use to layer on top of Network.framework on Apple platforms), and we should leverage that for Windows as well.

This is not to say that it's @compnerd 's responsibility to do the work, of course!