Original: WebSockets on IOS with Starscream
Aaron Douglas
Translator: Kmyhy
Traditional network technology (i.e. Berkeley sockets) is considered to be reliable and stable. But the Berkeley socket is not very good under certain web technologies, such as proxies and firewalls. WebSocket appeared in 2011 as a new technology to establish two-way communication between client and server. WebSocket is more efficient than multiple HTTP requests and allows for long connections.
It's not that easy to use WebSocket on IOS. The advent of IOS and Mac Library Starscream greatly simplifies the creation and use of WebSocket.
Note: This article assumes you are familiar with CocoaPods. If you are unfamiliar, please refer to our CocoaPods tutorial.
In this article, you will complete the Network Programming section in an App called Emoji Commuicator. Emoji Communicator allows you to publish your current mood with a Emoji character to all people connected to the service.
Emoji Communicator The original developer originally intended to use HTTP requests for new messages, but this feature is obviously more appropriate to use WebSocket. You will use Starscream to connect to the backend Web server.
Begin
First, you need a WEB server. In this article, you will start a Web server on this computer. The Web server for this example runs under node. JS and uses a small Javascript file to support it.
Of course, you first need to install node. js. If you are unsure if you are already installed, you can enter the command in the terminal window:
node--version
If you get an error, follow these steps to download and install node. js. Otherwise, you will see the version number of node. js, and you can skip the next section of node. js download.
Install and download node. js
Download the latest installation package for node. JS in https://nodejs.org/(the latest version of the current 2016.9.22 is). After downloading the installation package (for example, node-v6.6.0.pkg), double-click to install. Refer to the prompts, and select the default options on the line.
After the installation is complete, check that node. JS is working in the terminal:
node--version
If you don't see 6.6.0 (or the version you installed), or an error, check that the installation is correct again.
Chat server
You will be using a chat server. Download the sample IOS app and Web server code from here. Unzip the ZIP package to the desktop or to a folder. In the terminal, switch to the directory and enter the Nodeapp subdirectory.
This program requires a third-party module that needs to be installed with the node. JS Package Manager NPM. In this directory, execute:
install websocket
Enter the following command to start the chat server:
node chat-server.js
You will see output similar to the following:
13201618:54:44 GMT-0500isonport1337
Then open frontend.html in the browser Safari or Chrome.
Enter a nickname and send a test message. If you want to test on a second client, reopen a browser or tab, using the same Url. Log in with another nickname, send a message, and you'll see the message immediately appear in another browser.
This fully illustrates the strength of WebSocket. Each browser has a separate long connection to the Web server--no refresh. When a message arrives, the server automatically broadcasts to all connected clients. Back to the terminal, you can see all the chat activities:
$node Chat-server. jsTue Sep13 2016 18:: GMT-0500(CDT)Server is Listening on Port1337Tue Sep13 2016 18:: GMT-0500(CDT)Connection from Origin NULL.Tue Sep13 2016 18:: GMT-0500(CDT)Connection accepted.Tue Sep13 2016 18:: GMT-0500(CDT)User is known as:Aaron with Green Color.Tue Sep13 2016 18:: Panax Notoginseng GMT-0500(CDT)Received Message from Aaron:HelloTue Sep13 2016 18:: GMT-0500(CDT)Connection from Origin NULL.Tue Sep13 2016 18:: GMT-0500(CDT)Connection accepted.Tue Sep13 2016 18:: Wuyi GMT-0500(CDT)User is known as:James with Red Color.Tue Sep13 2016 18:: GMT-0500(CDT)Received Message from James: This is Pretty Slick!Tue Sep13 2016 18:: Geneva GMT-0500(CDT)Received Message from James: :]Tue Sep13 2016 18:: GMT-0500(CDT)Peer undefined Disconnected.
WebSockets
HTTP first appeared in 1991, and it was designed as a request-response communication mechanism. Web browsers work well with this mechanism, and users request Web pages and the server returns content. But sometimes, when new data is needed, the user is notified without a user's request-that is, the server pushes.
The HTTP protocol does not work well with push models. Before the advent of WebSocket, Web services implemented a push model through a series of browser refresh mechanisms, but the efficiency was not satisfactory.
WebSocket implements the service-side push mechanism. The new Web browser all supports WebSocket, which makes it super simple to use. With WebSocket you can open persistent connections, and most networks can easily handle WebSocket connections.
WebSocket are often used in scenarios where some data is constantly or frequently changing. For example, web notifications on Facebook, live chat in Slack, stock price changes in a trading system.
Using WebSocket in IOS is tricky, you have to do a lot of setup, and the built-in API doesn't help at all. Then Starscream appeared--this small, easy-to-use library has left all your troubles missing.
Emoji Communicator
Open Emojitransmitter.xcodeproj. Run the program in the emulator, the program is very simple, it requires the user to enter a nickname, and then display an interface, let the user select a emoji send, and display any received emoji.
The APP has not yet completed the network section. You will use Starscream to perform all WebSocket network requests.
There are many ways to integrate Starscream into your project. CocoaPods and Carthage are two of the most common package managers. Both of you can use it, but this article uses CocoaPods.
First, close the open project. Open the terminal window and switch the directory to the project folder. There is already a Podfile file configured with the Starscream pod in this project. You can install the pod directly:
update; pod install
When CocoaPods ends the installation, open the Emojitransmitter.xcworkspace file in Xcode 8. Run the program and check to see if the APP is running.
Open Viewcontroller.swift, add after import UIKit:
import Starscream
Then, add a property after the username property of the Viewcontroller class:
socketURL(string"ws://localhost:1337/")!, protocols: ["chat"])
This is the core of creating a WebSocket connection. Notice the URL of the song, the Protocol is WS instead of Http/https. The protocols parameter is specified as chat, depending on the implementation of the server, which can be used, or may be ignored. In this demo, you can ignore it.
Then add it after the Viewdidload method:
deinit { socket0) socket.delegate = nil}
Forces the WebSocket connection to close when the View Controller is destroyed.
All the work in Starscream is carried out in the delegate. Starscream also supports closures, if you do not want to use the delegate.
In Viewcontroller.swift, add an extension after the fileprivate extension:
// MARK: - WebSocketDelegateextension ViewController : WebSocketDelegate { publicwebsocketDidConnect(_ socket: Starscream.WebSocket) { } publicwebsocketDidDisconnect(_ socket: Starscream.WebSocket, error: NSError?) { } publicwebsocketDidReceiveMessage(_ socket: Starscream.WebSocket, text: String) { } publicwebsocketDidReceiveData(_ socket: Starscream.WebSocket, data: Data) { }}
These 4 delegate methods must be implemented, otherwise the code cannot be compiled.
Then, after Super.viewdidload () of the Viewdidload method, add:
socket.delegate = selfsocket.connect()
Run the program, enter a nickname, and click Next. Return to the node. JS console you will see a connection notification.
Now that you are able to connect to the node. JS APP, the next step is to send a message to the server.
First, the SendMessage (_:) Method is modified to:
messageString) { socket.write(stringmessage)}
This sends a message (in this case, emoji) to the node. JS server.
Then, in Websocketdidconnect (_:) method, add:
socket.write(string: username)
This will send the nickname you entered in the first interface after the connection is established. This server will treat the first received message as a user name.
In Websocketdiddisconnect (_:error:) Join in:
performSegue(withIdentifier: "websocketDisconnected", sender: self)
Whatever the reason, as long as the socket is disconnected, this will allow the user to return to the input nickname interface. If you're in your own App, you should have more robust error handling here.
Then, in Websocketdidreceivemessage (_:text:) Method:
//1Guard Letdata = Text.data (using:. Utf16), LetJsondata =Try? Jsonserialization.jsonobject (With:data), LetJsondict = Jsondata as? [String:any], LetMessageType = jsondict["Type"] as? StringElse{return}//2ifMessageType = ="Message", LetMessageData = jsondict["Data"] as? [String:any], LetMessageauthor = messagedata["Author"] as? String, LetMessageText = messagedata["Text"] as? String {messagereceived (MessageText, Sendername:messageauthor)}
The text message received is a readable string--if it is JSON, try to convert it to a collection object. The code is interpreted as follows:
- First, the string is converted to NSData, and then the NSData is passed to the Jsonserialization object to convert it to a vector and return a valid object. Finally, several important keys are checked and the corresponding values are set. If the object is not valid, exit directly through the guard statement.
- Filter the MessageType of the message and pass the data to Messagereceived (MessageText:, SenderName:) Method.
The following is an example of a JSON-formatted message received from node. JS:
{ "type"message", "data{ "time": 1472513071731, "text": ":]", "author": "iPhone Simulator", "color": "orange" }}
Run the app, and whenever you send a message, emoji will refresh with your chosen emoji and nickname. Back to the Web console, your emoji message will also be displayed.
This is the use of Starscream!
End
Download the final completed project here.
Emoji Communicator is one of the simplest examples of using WebSocket. If you want to use Starscream in a service that already exists, you can refer to more information:
- Refer to the Starscream Project homepage on GitHub.
- Refer to the Mozilla Developer Network for an introduction to WebSocket and how to implement WebSocket.
- If you need something that is sleepy, read RFC 6455, about the WebSocket protocol specification.
If you have any questions or suggestions, please leave a comment below.
WebSocket Framework on IOS Starscream