|
| 1 | +# SocketRocket |
| 2 | + |
| 3 | +![Platforms][platforms-svg] |
| 4 | +[![License][license-svg]][license-link] |
| 5 | + |
| 6 | +[![Podspec][podspec-svg]][podspec-link] |
| 7 | +[![Carthage Compatible][carthage-svg]](carthage-link) |
| 8 | + |
| 9 | +[![Build Status][build-status-svg]][build-status-link] |
| 10 | + |
| 11 | +A conforming WebSocket ([RFC 6455](https://tools.ietf.org/html/rfc6455>)) client library for iOS, macOS and tvOS. |
| 12 | + |
| 13 | +Test results for SocketRocket [here](http://facebook.github.io/SocketRocket/results/). |
| 14 | +You can compare to what modern browsers look like [here](http://autobahn.ws/testsuite/reports/clients/index.html). |
| 15 | + |
| 16 | +SocketRocket currently conforms to all core ~300 of [Autobahn](http://autobahn.ws/testsuite/>)'s fuzzing tests |
| 17 | +(aside from two UTF-8 ones where it is merely *non-strict* tests 6.4.2 and 6.4.4). |
| 18 | + |
| 19 | +## Features/Design |
| 20 | + |
| 21 | +- TLS (wss) support, including self-signed certificates. |
| 22 | +- Seems to perform quite well. |
| 23 | +- Supports HTTP Proxies. |
| 24 | +- Supports IPv4/IPv6. |
| 25 | +- Supports SSL certificate pinning. |
| 26 | +- Sends `ping` and can process `pong` events. |
| 27 | +- Asynchronous and non-blocking. Most of the work is done on a background thread. |
| 28 | +- Supports iOS, macOS, tvOS. |
| 29 | + |
| 30 | +## Installing |
| 31 | + |
| 32 | +There are a few options. Choose one, or just figure it out: |
| 33 | + |
| 34 | +- **[CocoaPods](https://cocoapods.org)** |
| 35 | + |
| 36 | + Add the following line to your Podfile: |
| 37 | + ```ruby |
| 38 | + pod 'SocketRocket' |
| 39 | + ``` |
| 40 | + Run `pod install`, and you are all set. |
| 41 | + |
| 42 | +- **[Carthage](https://github.com/carthage/carthage)** |
| 43 | + |
| 44 | + Add the following line to your Cartfile: |
| 45 | + ``` |
| 46 | + github "facebook/SocketRocket" |
| 47 | + ``` |
| 48 | + Run `carthage update`, and you should now have the latest version of `SocketRocket` in your `Carthage` folder. |
| 49 | + |
| 50 | +- **Using SocketRocket as a sub-project** |
| 51 | + |
| 52 | + You can also include `SocketRocket` as a subproject inside of your application if you'd prefer, although we do not recommend this, as it will increase your indexing time significantly. To do so, just drag and drop the `SocketRocket.xcodeproj` file into your workspace. |
| 53 | + |
| 54 | +## API |
| 55 | + |
| 56 | +### `SRWebSocket` |
| 57 | + |
| 58 | +The Web Socket. |
| 59 | + |
| 60 | +#### Note: |
| 61 | + |
| 62 | +`SRWebSocket` will retain itself between `-(void)open` and when it closes, errors, or fails. |
| 63 | +This is similar to how `NSURLConnection` behaves (unlike `NSURLConnection`, `SRWebSocket` won't retain the delegate). |
| 64 | + |
| 65 | +#### Interface |
| 66 | + |
| 67 | +```objective-c |
| 68 | +@interface SRWebSocket : NSObject |
| 69 | + |
| 70 | +// Make it with this |
| 71 | +- (instancetype)initWithURLRequest:(NSURLRequest *)request; |
| 72 | + |
| 73 | +// Set this before opening |
| 74 | +@property (nonatomic, weak) id <SRWebSocketDelegate> delegate; |
| 75 | + |
| 76 | +// Open with this |
| 77 | +- (void)open; |
| 78 | + |
| 79 | +// Close it with this |
| 80 | +- (void)close; |
| 81 | + |
| 82 | +// Send a Data |
| 83 | +- (void)sendData:(nullable NSData *)data error:(NSError **)error; |
| 84 | + |
| 85 | +// Send a UTF8 String |
| 86 | +- (void)sendString:(NSString *)string error:(NSError **)error; |
| 87 | + |
| 88 | +@end |
| 89 | +``` |
| 90 | +
|
| 91 | +### `SRWebSocketDelegate` |
| 92 | +
|
| 93 | +You implement this |
| 94 | +
|
| 95 | +```objective-c |
| 96 | +@protocol SRWebSocketDelegate <NSObject> |
| 97 | +
|
| 98 | +@optional |
| 99 | +
|
| 100 | +- (void)webSocketDidOpen:(SRWebSocket *)webSocket; |
| 101 | +
|
| 102 | +- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessageWithString:(NSString *)string; |
| 103 | +- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessageWithData:(NSData *)data; |
| 104 | +
|
| 105 | +- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error; |
| 106 | +- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(nullable NSString *)reason wasClean:(BOOL)wasClean; |
| 107 | +
|
| 108 | +@end |
| 109 | +``` |
| 110 | + |
| 111 | +## Testing |
| 112 | + |
| 113 | +Included are setup scripts for the python testing environment. |
| 114 | +It comes packaged with vitualenv so all the dependencies are installed in userland. |
| 115 | + |
| 116 | +To run the short test from the command line, run: |
| 117 | +```bash |
| 118 | + make test |
| 119 | +``` |
| 120 | + |
| 121 | +To run all the tests, run: |
| 122 | +```bash |
| 123 | + make test_all |
| 124 | +``` |
| 125 | + |
| 126 | +The short tests don't include the performance tests |
| 127 | +(the test harness is actually the bottleneck, not SocketRocket). |
| 128 | + |
| 129 | +The first time this is run, it may take a while to install the dependencies. It will be smooth sailing after that. |
| 130 | + |
| 131 | +You can also run tests inside Xcode, which runs the same thing, but makes it easier to debug. |
| 132 | + |
| 133 | +- Choose the `SocketRocket` target |
| 134 | +- Run the test action (`⌘+U`) |
| 135 | + |
| 136 | +### TestChat Demo Application |
| 137 | + |
| 138 | +SocketRocket includes a demo app, TestChat. |
| 139 | +It will "chat" with a listening websocket on port 9900. |
| 140 | + |
| 141 | +#### TestChat Server |
| 142 | + |
| 143 | +The sever takes a message and broadcasts it to all other connected clients. |
| 144 | + |
| 145 | +It requires some dependencies though to run. |
| 146 | +We also want to reuse the virtualenv we made when we ran the tests. |
| 147 | +If you haven't run the tests yet, go into the SocketRocket root directory and type: |
| 148 | + |
| 149 | +```bash |
| 150 | +make test |
| 151 | +``` |
| 152 | + |
| 153 | +This will set up your [virtualenv](https://pypi.python.org/pypi/virtualenv). |
| 154 | + |
| 155 | +Now, in your terminal: |
| 156 | + |
| 157 | +```bash |
| 158 | +source .env/bin/activate |
| 159 | +pip install git+https://github.com/tornadoweb/tornado.git |
| 160 | +``` |
| 161 | + |
| 162 | +In the same terminal session, start the chatroom server: |
| 163 | + |
| 164 | +```bash |
| 165 | +python TestChatServer/py/chatroom.py |
| 166 | +``` |
| 167 | + |
| 168 | +There's also a Go implementation (with the latest weekly) where you can: |
| 169 | + |
| 170 | +```bash |
| 171 | +cd TestChatServer/go |
| 172 | +go run chatroom.go |
| 173 | +``` |
| 174 | + |
| 175 | +#### Chatting |
| 176 | + |
| 177 | +Now, start TestChat.app (just run the target in the Xcode project). |
| 178 | +If you had it started already you can hit the refresh button to reconnect. |
| 179 | +It should say "Connected!" on top. |
| 180 | + |
| 181 | +To talk with the app, open up your browser to [http://localhost:9000](http://localhost:9000) and start chatting. |
| 182 | + |
| 183 | + |
| 184 | +## WebSocket Server Implementation Recommendations |
| 185 | + |
| 186 | +SocketRocket has been used with the following libraries: |
| 187 | + |
| 188 | +- [Tornado](https://github.com/tornadoweb/tornado) |
| 189 | +- Go's [WebSocket package](https://godoc.org/golang.org/x/net/websocket) or Gorilla's [version](http://www.gorillatoolkit.org/pkg/websocket). |
| 190 | +- [Autobahn](http://autobahn.ws/testsuite/) (using its fuzzing client). |
| 191 | + |
| 192 | +The Tornado one is dirt simple and works like a charm. |
| 193 | +([IPython notebook](http://ipython.org/ipython-doc/dev/interactive/htmlnotebook.html) uses it too). |
| 194 | +It's much easier to configure handlers and routes than in Autobahn/twisted. |
| 195 | + |
| 196 | +## Contributing |
| 197 | + |
| 198 | +We’re glad you’re interested in SocketRocket, and we’d love to see where you take it. |
| 199 | +Please read our [contributing guidelines](https://github.com/facebook/SocketRocket/blob/master/CONTRIBUTING.md) prior to submitting a Pull Request. |
| 200 | + |
| 201 | + [build-status-svg]: https://img.shields.io/travis/facebook/SocketRocket/master.svg |
| 202 | + [build-status-link]: https://travis-ci.org/facebook/SocketRocket/branches |
| 203 | + |
| 204 | + [license-svg]: https://img.shields.io/badge/license-BSD-lightgrey.svg |
| 205 | + [license-link]: https://github.com/BoltsFramework/SocketRocket/blob/master/LICENSE |
| 206 | + |
| 207 | + [podspec-svg]: https://img.shields.io/cocoapods/v/SocketRocket.svg |
| 208 | + [podspec-link]: https://cocoapods.org/pods/SocketRocket |
| 209 | + |
| 210 | + [carthage-svg]: https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat |
| 211 | + [carthage-link]: https://github.com/carthage/carthage |
| 212 | + |
| 213 | + [platforms-svg]: http://img.shields.io/cocoapods/p/SocketRocket.svg?style=flat |
0 commit comments