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.
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.
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?
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.
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.
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.
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.
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!