From 2ac6fa06e8bc8beb867f5f3fbf82391c0cca3a19 Mon Sep 17 00:00:00 2001 From: tanner0101 Date: Wed, 18 Apr 2018 13:32:03 -0400 Subject: [PATCH] add websocket docs --- 3.0/docs/http/getting-started.md | 2 +- 3.0/docs/http/message.md | 2 +- 3.0/docs/websocket/getting-started.md | 40 ++++++++++++ 3.0/docs/websocket/overview.md | 94 +++++++++++++++++++++++++++ 3.0/docs/websocket/websocket.md | 3 - 3.0/mkdocs.yml | 3 +- 6 files changed, 138 insertions(+), 6 deletions(-) create mode 100644 3.0/docs/websocket/getting-started.md create mode 100644 3.0/docs/websocket/overview.md delete mode 100644 3.0/docs/websocket/websocket.md diff --git a/3.0/docs/http/getting-started.md b/3.0/docs/http/getting-started.md index 891f7e89..edce69e8 100644 --- a/3.0/docs/http/getting-started.md +++ b/3.0/docs/http/getting-started.md @@ -1,6 +1,6 @@ # Getting Started with HTTP -HTTP ([vapor/http](https://github.com/vapor/http)) is a non-blocking, event-driven HTTP library built on Swift NIO. It makes working with Swift NIO's HTTP handlers easy and offers higher level functionality like media types, client upgrading, streaming bodies, and more. Creating an HTTP echo server takes ~15 lines of code. +HTTP ([vapor/http](https://github.com/vapor/http)) is a non-blocking, event-driven HTTP library built on Swift NIO. It makes working with Swift NIO's HTTP handlers easy and offers higher level functionality like media types, client upgrading, streaming bodies, and more. Creating an HTTP echo server takes just a few lines of code. !!! tip If you use Vapor, most of HTTP's APIs will be wrapped by more convenient methods. Usually the only HTTP type you diff --git a/3.0/docs/http/message.md b/3.0/docs/http/message.md index 3ad9b7d2..662e45d3 100644 --- a/3.0/docs/http/message.md +++ b/3.0/docs/http/message.md @@ -1,4 +1,4 @@ -# Using HTTPMessage +# Using HTTP Message There are two types of HTTP messages, [`HTTPRequest`](#fixme) and [`HTTPResponse`](#fixme). For the most part they are very similar, but there are a couple of differences. diff --git a/3.0/docs/websocket/getting-started.md b/3.0/docs/websocket/getting-started.md new file mode 100644 index 00000000..8c8f0a10 --- /dev/null +++ b/3.0/docs/websocket/getting-started.md @@ -0,0 +1,40 @@ +# Getting Started with WebSocket + +WebSocket ([vapor/websocket](https://github.com/vapor/websocket)) is a non-blocking, event-driven WebSocket library built on Swift NIO. It makes working with Swift NIO's WebSocket handlers easy and provides integration with [HTTP](../http/getting-started) clients and servers. Creating an WebSocket echo server takes just a few lines of code. + +!!! tip + If you use Vapor, most of WebSocket's APIs will be wrapped by more convenient methods. + +## Vapor + +This package is included with Vapor and exported by default. You will have access to all `WebSocket` APIs when you import `Vapor`. + +```swift +import Vapor +``` + +## Standalone + +The WebSocket package is lightweight, pure-Swift, and only depends in Swift NIO. This means it can be used as an WebSocket framework any Swift project—even one not using Vapor. + +To include it in your package, add the following to your `Package.swift` file. + +```swift +// swift-tools-version:4.0 +import PackageDescription + +let package = Package( + name: "Project", + dependencies: [ + ... + .package(url: "https://github.com/vapor/websocket.git", from: "1.0.0"), + ], + targets: [ + .target(name: "Project", dependencies: ["WebSocket", ... ]) + ] +) +``` + +Use `import WebSocket` to access the APIs. + +The rest of this guide will give you an overview of what is available in the WebSocket package. As always, feel free to visit the [API docs](http://api.vapor.codes/websocket/latest/WebSocket/index.html) for more in-depth information. \ No newline at end of file diff --git a/3.0/docs/websocket/overview.md b/3.0/docs/websocket/overview.md new file mode 100644 index 00000000..970ed7f2 --- /dev/null +++ b/3.0/docs/websocket/overview.md @@ -0,0 +1,94 @@ +# Using WebSockets + +Unlike HTTP, WebSockets allow you to communicate between client and server in an open, interactive way. You can send messages (called frames) in either text or binary format. Both the client and the server can send as many messages as they want at a time, without having to wait for responses. + +Although WebSocket is its own protocol, it still uses HTTP to get setup. Every WebSocket connection will start with an HTTP request with special headers followed by an HTTP response with status `101 Switching Protocols`. After this initial handshake, the connection is a WebSocket connection. + +## WebSocket + +The [`WebSocket`](#fixme) class represents a connected WebSocket client. You can use this to set callbacks for receiving data and to send data. + +```swift +let ws: WebSocket = ... +// Send an initial message to this WebSocket +ws.send("Hello!") + +// Set a new callback for receiving text formatted data +ws.onText { ws, string in + // Echo the text back, reversed. + ws.send(string.reversed()) +} +``` + +!!! tip + All callbacks will receive a reference to the `WebSocket`. Use these if you need to send data to avoid creating a reference cycle. + +The `WebSocket` has an [`onClose`](#fixme) future that will be completed when the connection closes. You can use [`close()`](#fixme) to close the connection yourself. + +## Server + +WebSocket servers connect to one or more WebSocket clients at a time. As mentioned previously, WebSocket connections must start via an HTTP request and response handshake. Because of this, WebSocket servers are built on top of [HTTP servers](../http/server.md) using the HTTP upgrade mechanism. + +```swift +// First, create an HTTPProtocolUpgrader +let ws = WebSocket.httpProtocolUpgrader(shouldUpgrade: { req in + // Returning nil in this closure will reject upgrade + if req.url.path == "/deny" { return nil } + // Return any additional headers you like, or just empty + return [:] +}, onUpgrade: { ws, req in + // This closure will be called with each new WebSocket client + ws.send("Connected") + ws.onText { ws, string in + ws.send(string.reversed()) + } +}) + +// Next, create your server, adding the WebSocket upgrader +let server = try HTTPServer.start( + ... + upgraders: [ws], + ... +).wait() +// Run the server. +try server.onClose.wait() +``` + +!!! seealso + Visit [HTTP → Server](../http/server.md) for more information on setting up an HTTP server. + +The WebSocket protocol upgrader consists of two callbacks. + +The first callback `shouldUpgrade` receives the incoming HTTP request that is requesting upgrade. This callback decides whether or not to complete the upgrade based on the contents of the request. If `nil` is returned in this closure, the upgrade will be rejected. + +The second callback `onUpgrade` is called each time a new WebSocket client connects. This is where you configure your callbacks and send any initial data. + +!!! warning + The upgrade closures may be called on any event loop. Be careful to avoid race conditions if you must access external variables. + +## Client + +You can also use the WebSocket package to connect _to_ a WebSocket server. Just like the WebSocket server used an HTTP server, the WebSocket client uses HTTP client. + +```swift +// Create a new WebSocket connected to echo.websocket.org +let ws = try HTTPClient.webSocket(hostname: "echo.websocket.org", on: ...).wait() + +// Set a new callback for receiving text formatted data. +ws.onText { ws, text in + print("Server echo: \(text)") +} + +// Send a message. +ws.send("Hello, world!") + +// Wait for the Websocket to closre. +try ws.onClose.wait() +``` + +!!! seealso + Visit [HTTP → Client](../http/client.md) for more information on setting up an HTTP client. + +## API Docs + +Check out the [API docs](https://api.vapor.codes/websocket/latest/WebSocket/index.html) for more in-depth information about all of the methods. diff --git a/3.0/docs/websocket/websocket.md b/3.0/docs/websocket/websocket.md deleted file mode 100644 index 01f768e5..00000000 --- a/3.0/docs/websocket/websocket.md +++ /dev/null @@ -1,3 +0,0 @@ -# WebSocket - -Coming soon. \ No newline at end of file diff --git a/3.0/mkdocs.yml b/3.0/mkdocs.yml index 9847f447..0d8508c3 100644 --- a/3.0/mkdocs.yml +++ b/3.0/mkdocs.yml @@ -104,7 +104,8 @@ pages: - 'Getting Started': 'vapor/getting-started.md' - 'Content': 'vapor/content.md' - 'WebSocket': - - 'Getting Started': 'websocket/websocket.md' + - 'Getting Started': 'websocket/getting-started.md' + - 'Overview': 'websocket/overview.md' - 'Version (3.0-rc)': - '1.5': 'version/1_5.md' - '2.0': 'version/2_0.md'