Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/fukamachi/websocket-driver
WebSocket server/client implementation for Common Lisp
https://github.com/fukamachi/websocket-driver
common-lisp websocket
Last synced: about 2 months ago
JSON representation
WebSocket server/client implementation for Common Lisp
- Host: GitHub
- URL: https://github.com/fukamachi/websocket-driver
- Owner: fukamachi
- License: bsd-2-clause
- Created: 2014-09-21T05:27:58.000Z (over 10 years ago)
- Default Branch: master
- Last Pushed: 2024-07-09T11:55:12.000Z (7 months ago)
- Last Synced: 2024-10-31T11:45:59.421Z (3 months ago)
- Topics: common-lisp, websocket
- Language: Common Lisp
- Homepage:
- Size: 120 KB
- Stars: 104
- Watchers: 13
- Forks: 28
- Open Issues: 20
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Websocket Driver
[![Build Status](https://travis-ci.org/fukamachi/websocket-driver.svg?branch=master)](https://travis-ci.org/fukamachi/websocket-driver)
[![Quicklisp dist](http://quickdocs.org/badge/websocket-driver.svg)](http://quickdocs.org/websocket-driver/)This library provides WebSocket server & client implementation for Common Lisp.
## Supported Servers
* [Hunchentoot](http://weitz.de/hunchentoot/)
* [Wookie](http://wookie.lyonbros.com)
* [Woo](https://github.com/fukamachi/woo)## Usage
### Server-side with Clack
WebSocket server implementation is designed to work with [Clack](https://github.com/fukamachi/clack), which is a abstraction layer for web servers.
```common-lisp
(ql:quickload '(:websocket-driver-server :clack))(use-package :websocket-driver)
(defvar *echo-server*
(lambda (env)
(let ((ws (make-server env)))
(on :message ws
(lambda (message)
(send ws message)))
(lambda (responder)
(declare (ignore responder))
(start-connection ws)))));; Start Wookie server
(clack:clackup *echo-server* :server :wookie :port 5000)
```The backend server can be changed by replacing `:wookie` by other servers.
### Client-side
```common-lisp
(ql:quickload :websocket-driver-client)(defvar *client* (wsd:make-client "ws://localhost:5000/echo"))
(wsd:start-connection *client*)
(wsd:on :message *client*
(lambda (message)
(format t "~&Got: ~A~%" message)))
(wsd:send *client* "Hi")
(wsd:close-connection *client*)
```## APIs
### \[Function] make-server (env &key max-length accept-protocols additional-headers)
Returns a new `SERVER` object. The `ENV` is a property list represents server information, which [Clack](http://clacklisp.org) provides.
The `max-length` is the maximum message size allowed. The default is `#x3ffffff`. If at any time it stays bigger than this, the connection will be closed with code 1009 (too-large).
The `accept-protocols` is a list of custom protocol names as strings. This will be used for checking `Sec-WebSocket-Protocol` header client sent. The default is an empty list.
The `additional-headers` is an association list which represents HTTP headers to use in WebSocket handshake response. The default is an empty list.
### \[Function] make-client (url &key max-length accept-protocols additional-headers)
Returns a new `CLIENT` object. The `URL` is a string to connect.
Additional keyword arguments `max-length`, `accept-protocols` and `additional-headers` are shared with `make-server`.
### \[Class] ws
The base class for `server` and `client`.
As this inherits `event-emitter`, its object can be attached event listerners by `on`.
#### \[Event] :open
Called when the socket becomes open.
```common-lisp
(on :open ws
(lambda ()
(format t "Connected.~%")))
```#### \[Event] :message
Called when a message is received. The callback function takes a `MESSAGE` as an argument which is either a string in the case of a text message or an `(UNSIGNED-BYTE 8)` vector in the case of a binary message.
```common-lisp
(on :message ws
(lambda (message)
(format t "Received: ~S~%" message)))
```#### \[Event] :error
Called when a protocol error occurs due to the other peer sending an invalid byte sequence. The callback function takes a `PROTOCOL-ERROR` as an argument.
```common-lisp
(on :error ws
(lambda (error)
(format t "Got an error: ~S~%" error)))
```#### \[Event] :close
Called when the socket becomes closed. The `CALLBACK` function takes `CODE` and `REASON` as arguments.
```common-lisp
(on :close ws
(lambda (&key code reason)
(format t "Closed because '~A' (Code=~A)~%" reason code)))
```### \[Class] server
The class for WebSocket (version 13) server implementation.
### \[Class] client
The class for WebSocket client implementation.
### \[Method] `(start-connection ws)`
Initiates the protocol by sending the handshake - either the response for a server-side driver or the request for a client-side one. This should be the first method you invoke. Returns `T` if a handshake was sent.
### \[Method] `(send ws data &key start end type code callback)`
Sends `DATA` over the socket.
### \[Function] `(send-text ws message &key start end callback)`
Sends a text message over the socket.
### \[Function] `(send-binary ws usb8-vector &key start end callback)`
Takes an `(UNSIGNED-BYTE 8)` vector and sends them as a binary message.
### \[Method] `(send-ping ws &optional message callback)`
Sends a ping frame over the socket, queueing it if necessary.
### \[Method] `(close-connection ws)`
Initiates the closing handshake if the socket is still open.
### \[Method] `(version driver)`
Returns the WebSocket version in use as a string (ex. "hybi-13").
### \[Method] `(protocol driver)`
Returns a string containing the selected subprotocol, if any was agreed upon using the `Sec-WebSocket-Protocol` mechanism.
### \[Method] `(ready-state ws)`
Returns the connection state as a keyword, which is one of `:connecting`, `:open`, `:closing` and `:closed`.
## Author
* Eitaro Fukamachi ([email protected])
## Copyright
Copyright (c) 2014 Eitaro Fukamachi ([email protected])
## License
Licensed under the BSD 2-Clause License.
## See Also
* [Clack](http://clacklisp.org)
* [Event Emitter](https://github.com/fukamachi/event-emitter)