123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- SocketRocket Objective-C WebSocket Client (beta)
- ================================================
- A conforming WebSocket (`RFC 6455 <http://tools.ietf.org/html/rfc6455>`_)
- client library.
- `Test results for SocketRocket here <http://square.github.io/SocketRocket/results/>`_.
- You can compare to what `modern browsers look like here
- <http://tavendo.com/autobahn/testsuite/report/clients/index.html>`_.
- SocketRocket currently conforms to all ~300 of `Autobahn
- <http://autobahn.ws/testsuite/>`_'s fuzzing tests (aside from
- two UTF-8 ones where it is merely *non-strict*. tests 6.4.2 and 6.4.4)
- Features/Design
- ---------------
- - TLS (wss) support. It uses CFStream so we get this for *free*
- - Uses NSStream/CFNetworking. Earlier implementations used ``dispatch_io``,
- however, this proved to be make TLS nearly impossible. Also I wanted this to
- work in iOS 4.x. (SocketRocket only supports 5.0 and above now)
- - Uses ARC. It uses the 4.0 compatible subset (no weak refs).
- - Seems to perform quite well
- - Parallel architecture. Most of the work is done in background worker queues.
- - Delegate-based. Had older versions that could use blocks too, but I felt it
- didn't blend well with retain cycles and just objective C in general.
- Changes
- -------
- v0.3.1-beta2 - 2013-01-12
- `````````````````````````
- - Stability fix for ``closeWithCode:reason:`` (Thanks @michaelpetrov!)
- - Actually clean up the NSStreams and remove them from their runloops
- - ``_SRRunLoopThread``'s ``main`` wasn't correctly wrapped with
- ``@autoreleasepool``
- v0.3.1-beta1 - 2013-01-12
- `````````````````````````
- - Cleaned up GCD so OS_OBJECT_USE_OBJC_RETAIN_RELEASE is optional
- - Removed deprecated ``dispatch_get_current_queue`` in favor of ``dispatch_queue_set_specific`` and ``dispatch_get_specific``
- - Dropping support for iOS 4.0 (it may still work)
- Installing (iOS)
- ----------------
- There's a few options. Choose one, or just figure it out
- - You can copy all the files in the SocketRocket group into your app.
- - Include SocketRocket as a subproject and use libSocketRocket
- If you do this, you must add -ObjC to your "other linker flags" option
- - For OS X you will have to repackage make a .framework target. I will take
- contributions. Message me if you are interested.
- Depending on how you configure your project you may need to ``#import`` either
- ``<SocketRocket/SRWebSocket.h>`` or ``"SRWebSocket.h"``
- Framework Dependencies
- ``````````````````````
- Your .app must be linked against the following frameworks/dylibs
- - libicucore.dylib
- - CFNetwork.framework
- - Security.framework
- - Foundation.framework
- Installing (OS X)
- -----------------
- SocketRocket now has (64-bit only) OS X support. ``SocketRocket.framework``
- inside Xcode project is for OS X only. It should be identical in function aside
- from the unicode validation. ICU isn't shipped with OS X which is what the
- original implementation used for unicode validation. The workaround is much
- more rudimentary and less robust.
- 1. Add SocketRocket.xcodeproj as either a subproject of your app or in your workspace.
- 2. Add ``SocketRocket.framework`` to the link libraries
- 3. If you don't have a "copy files" step for ``Framework``, create one
- 4. Add ``SocketRocket.framework`` to the "copy files" step.
- API
- ---
- The classes
- ``SRWebSocket``
- ```````````````
- The Web Socket.
- .. note:: ``SRWebSocket`` will retain itself between ``-(void)open`` and when it
- closes, errors, or fails. This is similar to how ``NSURLConnection`` behaves.
- (unlike ``NSURLConnection``, ``SRWebSocket`` won't retain the delegate)
- What you need to know
- .. code-block:: objective-c
- @interface SRWebSocket : NSObject
- // Make it with this
- - (id)initWithURLRequest:(NSURLRequest *)request;
- // Set this before opening
- @property (nonatomic, assign) id <SRWebSocketDelegate> delegate;
- - (void)open;
-
- // Close it with this
- - (void)close;
- // Send a UTF8 String or Data
- - (void)send:(id)data;
- @end
- ``SRWebSocketDelegate``
- ```````````````````````
- You implement this
- .. code-block:: objective-c
- @protocol SRWebSocketDelegate <NSObject>
- - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message;
- @optional
- - (void)webSocketDidOpen:(SRWebSocket *)webSocket;
- - (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error;
- - (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean;
- @end
- Known Issues/Server Todo's
- --------------------------
- - Needs auth delegates (like in NSURLConnection)
- - Move the streams off the main runloop (most of the work is backgrounded uses
- GCD, but I just haven't gotten around to moving it off the main loop since I
- converted it from dispatch_io)
- - Re-implement server. I removed an existing implementation as well because it
- wasn't being used and I wasn't super happy with the interface. Will revisit
- this.
- - Separate framer and client logic. This will make it nicer when having a
- server.
- Testing
- -------
- Included are setup scripts for the python testing environment. It comes
- packaged with vitualenv so all the dependencies are installed in userland.
- To run the short test from the command line, run::
- make test
- To run all the tests, run::
- make test_all
- The short tests don't include the performance tests. (the test harness is
- actually the bottleneck, not SocketRocket).
- The first time this is run, it may take a while to install the dependencies. It
- will be smooth sailing after that. After the test runs the makefile will open
- the results page in your browser. If nothing comes up, you failed. Working on
- making this interface a bit nicer.
- To run from the app, choose the ``SocketRocket`` target and run the test action
- (``cmd+u``). It runs the same thing, but makes it easier to debug. There is
- some serious pre/post hooks in the Test action. You can edit it to customize
- behavior.
- .. note:: Xcode only up to version 4.4 is currently supported for the test
- harness
- TestChat Demo Application
- -------------------------
- SocketRocket includes a demo app, TestChat. It will "chat" with a listening
- websocket on port 9900.
- It's a simple project. Uses storyboard. Storyboard is sweet.
- TestChat Server
- ```````````````
- We've included a small server for the chat app. It has a simple function.
- It will take a message and broadcast it to all other connected clients.
- We have to get some dependencies. We also want to reuse the virtualenv we made
- when we ran the tests. If you haven't run the tests yet, go into the
- SocketRocket root directory and type::
- make test
- This will set up your `virtualenv <https://pypi.python.org/pypi/virtualenv>`_.
- Now, in your terminal::
- source .env/bin/activate
- pip install git+https://github.com/tornadoweb/tornado.git
- In the same terminal session, start the chatroom server::
- python TestChatServer/py/chatroom.py
- There's also a Go implementation (with the latest weekly) where you can::
- cd TestChatServer/go
- go run chatroom.go
- Chatting
- ````````
- Now, start TestChat.app (just run the target in the Xcode project). If you had
- it started already you can hit the refresh button to reconnect. It should say
- "Connected!" on top.
- To talk with the app, open up your browser to `http://localhost:9000 <http://localhost:9000>`_ and
- start chatting.
- WebSocket Server Implementation Recommendations
- -----------------------------------------------
- SocketRocket has been used with the following libraries:
- - `Tornado <https://github.com/facebook/tornado>`_
- - Go's `WebSocket package <https://godoc.org/golang.org/x/net/websocket>`_ or Gorilla's `version <http://www.gorillatoolkit.org/pkg/websocket>`_
- - `Autobahn <http://tavendo.com/autobahn/testsuite.html>`_ (using its fuzzing
- client)
- The Tornado one is dirt simple and works like a charm. (`IPython notebook
- <http://ipython.org/ipython-doc/dev/interactive/htmlnotebook.html>`_ uses it
- too). It's much easier to configure handlers and routes than in
- Autobahn/twisted.
- As far as Go's goes, it works in my limited testing. I much prefer go's
- concurrency model as well. Try it! You may like it.
- It could use some more control over things such as pings, etc., but I
- am sure it will come in time.
- Autobahn is a great test suite. The Python server code is good, and conforms
- well (obviously). However for me, twisted would be a deal-breaker for writing
- something new. I find it a bit too complex and heavy for a simple service. If
- you are already using twisted though, Autobahn is probably for you.
- Contributing
- ------------
- We’re glad you’re interested in SocketRocket, and we’d love to see where you take it. Please read our `contributing guidelines <https://github.com/square/SocketRocket/blob/master/Contributing.md>`_ prior to submitting a Pull Request.
|