TCP Server With the SwiftNIO Networking Framework
Mobile developers often work with REST APIs or other networking protocols in their applications to access data or to coordinate activities. In this tutorial you will create a Swift Server with SwiftNIO, a low-level networking framework that makes creating TCP servers easier than before. By David Okun.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
TCP Server With the SwiftNIO Networking Framework
20 mins
- Getting Started
- Swift-on-the-Server Status Quo
- How SwiftNIO Differs You complete me, NIO.
- Setting Up Quote of the Day
- Running the iOS Client
- Setting Up Your Server Project
- Bootstrapping a Server
- Handling Incoming Requests With ChannelInboundHandler
- Polishing Off Your Server Functionality
- Running Your Server
- Where to Go From Here?
Mobile developers often work with REST APIs or other networking protocols in their applications — whether it’s to retrieve data, communicate with other devices, or something else. SwiftNIO, written by Apple, is a low-level networking framework that makes writing Swift servers even easier than before, empowering Swift developers to leverage their skills on the server side.
In this tutorial, you’ll:
- Learn about what purpose SwiftNIO serves and why Apple made and open-sourced it.
- Practice working within a SwiftNIO framework by creating a Quote Of The Day Swift TCP server that you’ll connect to using a provided iOS app.
To start, you’ll need a Mac running at least macOS 10.12 Sierra with Xcode 9.3 or later. You’ll also use the command line, so be sure to open up Terminal, and check the command line utility for Swift is installed. You can check this by entering swift –version. It must be version 4.1 or later.
Getting Started
First, it’s helpful to understand exactly how the SwiftNIO framework differs from other Swift frameworks.
Swift-on-the-Server Status Quo
If you’re a Swift developer, it’s very likely you’ve focused only on mobile applications. This makes servers in the cloud seem like voodoo magic — or at least a little confusing at first.
Thankfully, if you know Swift, frameworks like Kitura and Vapor make writing a web service easier.
However, these frameworks operate as a convenient layer on top of some sophisticated and low-level socket networking code, much of which interoperates with C. In the case of Kitura, once Swift became open sourced and available for Linux, IBM wrote BlueSocket to serve as its low-level socket networking layer.
How SwiftNIO Differs
BlueSocket is great, but it doesn’t fill in all the blanks when it comes to server-side Swift. For example, Kitura not only included the work of BlueSocket, but it also implemented the entire HTTP stack under the hood, so incoming communication would be routed the right way. Now, Apple has raised the bar, introducing SwiftNIO and essentially handling socket communication and HTTP for us.
This tutorial won’t go into great detail about every piece of the above diagram but, as you work your way through, each piece should begin to make sense. However, it’s worth explaining what an EventLoopGroup
is and, thus, what a MultiThreadedEventLoopGroup
accomplishes with this class.
EventLoopGroup and MultiThreadedEventLoopGroup
An EventLoop
runs in a loop, looking for new tasks to handle that have come in from a new client via a network connection. Think of an EventLoop
like a serial DispatchQueue
, which allows you to delegate blocks of code for execution at a time of your choosing. As multiple EventLoop
instances cycle through your thread, they look for tasks to execute.
When you put these EventLoop
instances into an EventLoopGroup
, the handler looks more like a concurrent DispatchQueue
. You can also think of this like a thread pool. This means you can submit multiple tasks to the group and, depending on the time it takes to complete each task, the order of completed tasks may not be what you initially submitted to the group.
This is where the MultiThreadedEventLoopGroup
class comes in. This specifies the EventLoopGroup
that’s created will tie each group to a specific thread, further streamlining your asynchronous operations that come in. Think of it like an upgraded EventLoopGroup
.
Synchronous/Asynchronous Example
Let’s say you’re at a food truck operated by one person. The person at the front of the line orders his food. He pays; he waits. He gets his food. The next person repeats this same process. The food truck delivers everyone’s order correctly, but it’s very slow. If you’re at the end of the line, you are pretty unhappy.
This is an example of a synchronous operation — something that blocks all other work until the current request is completed. A connection to a PostgreSQL database is another example.
Now, imagine the same food truck has an order-taker and two chefs. The person at the front of the line orders his food. He pays; he waits. But wait! The second person can now order his food without having to wait for the operator to complete the order for the first person. And the first person only has to wait for one other person. Here, the chefs are the EventLoopGroups making the food.
This is an example of a set of asynchronous operations. Ultimately, you’re waiting on the available resources of the service. But this new setup can handle multiple requests at the same time. The end user will see an increase in performance.
Another example of this is… well, SwiftNIO!
Setting Up Quote of the Day
To kick things off, download the materials for this tutorial; you can find a link at the top or bottom of this tutorial. You’ll be implementing a server called Quote of the Day — believe it or not, Quote of the Day (QOTD) is a real internet standard (RFC). You can read the protocol spec here.
The flow of information from the server works as follows:
- Open a TCP connection upon request.
- Write a random quote to the response.
- Send the response.
- Close the connection.
If you take a look at the RFC for Quote of the Day, you’ll notice two key things that you’ll do differently in this tutorial:
- You’ll use port 1717 instead of 17. Port 17 is locked down, requiring root permissions on macOS.
- You’ll only create a TCP/IP connection, not a UDP connection. As of this writing, UDP is still a work-in-progress on SwiftNIO (so many acronyms!).
For this tutorial, you’ll also use an iOS client to check that the server works properly. This iOS client uses BlueSocket — you won’t be making any changes to the iOS app, but feel free to look through the source code on your own.