/wol-websockets

Clojure Wrapper over Netty for simple and efficient use of websockets

Primary LanguageClojure

# wol-websockets

A thin Clojure Wrapper over Netty's serverside Websocket
implementation. Because websockets remain in such dramatic flux, I will strive to
keep this project based on the most recent Netty build
available("4.0.0.Alpha1-SNAPSHOT" as of this writing), ensuring that
largest number of Websocket versions are supported.

Essentially, I became sick of having to depend on additional libraries
to utilize WebSockets.  Ultimately, most sane jvm frameworks
themselves utilize  Netty, so why not just cut out the middle man?

## Usage
(server/start-netty-server
           {:message-received     wsocket-receive
	    :channel-connected    channel-disconnected
	    :channel-disconnected    channel-disconnected
            :post-ws-handshake    (make-post-ws-handshake)
            :port 8081})

The port argument determines the LISTEN port of the ws endpoint while
the remaining key/values are devoted to callbacks. All callbacks
besides :message-received are optional.

:message-received (fn [str-message-from-websocket] )

Called when a new message has be received from the client


:post-ws-handshake   (fn []
		        (ws-respond "welcome new client.  here is your initialization configuration" ))

Called after the websocket handshake has been completed and the HTTP connection
upgraded.  Useful for providing newly connected clients with
initialization instructions.


:channel-connected (fn [netty-context netty-event] )

Called by netty in the upstream pipeline on a channel which has been opened,
bound to a local address, and connected to a remote address.  This
code will be executed in a Boss thread and as such  must be performant
as it will block dispatching to workers.  Practically speaking, if you
aren't familiar with Netty, you probably do not care about this.


:channel-disconnected (fn [netty-context netty-event] )

Called by netty when a channel has disconnected from its remote peer. Practically speaking, if you
aren't familiar with Netty, you probably do not care about it.


##Sending Messages to Clients
*web-sockets* : WOL-Websockets  maintains an atom of all currently connected clients in server.clj

*web-socket* : Additionally a binding is setup for your message-received
 handler, granting access to the underlying netty channel. 
 eg. :message-receive (fn [str-message-from-websocket] 
                         (.write *web-socket* (TextWebSocketFrame. "some message"))


The convenience functions ws-respond, ws-broadcast-others, and
ws-broadcast-all exist for your benefit and automatically make use of
the above Vars.
 eg. :message-receive (fn [str-message-from-websocket] 
                         (ws-respond "some message"))


(ws-respond some-string) : Send a WebSocket response over the Netty channel
 currently bound to *web-socket* 

(ws-broadcast-others some-string) : Transmit a message to all clients
OTHER than the one currently bound to *web-socket*.  Useful for
informing all clients about the actions taken by one.

(ws-broadcast-all some-string) : Transmit a message to ALL clients.
Need not be called in the message-receive handler as the *web-socket*
binding is ignored. 

## License

Information wants to be free.