hunchen.io provides socket.io compatible functionality for the Hunchentoot web server. In effect, it can be used as a drop-in replacement for socket.io's server part.
This is work in progress.
hunchen.io is supported by and available through asdf-install and (soon) Quicklisp.
hunchen.io supports the only existing socket.io standard available at the time of writing, [version 1] socket.io-spec. Of all the available underlying transports specified however, only WebSockets are supported, through Hunchensocket. Multiple endpoints are not implemented at all, currently.
Just like Hunchensocket, hunchen.io is meant to be used as a Hunchentoot
extension. Because of the hard Hunchensocket dependency for WebSockets, you need
to follow the Hunchentoot
documentation but exchange the regular
HUNCHENTOOT:ACCEPTOR
and HUNCHENTOOT:SSL-ACCEPTOR
with
HUNCHENSOCKET:WEBSOCKET-ACCEPTOR
and HUNCHENSOCKET:WEBSOCKET-SSL-ACCEPTOR
,
respectively.
You'll need at least one socket.io end-point as well which is created by calling
DEFINE-SOCKET.IO-HANDLER
passing it a function λ message
which will be
called in turn for non-event messages (types 3 and 4 in the
[spec] socket.io-spec). For event messages (type 5), use
SOCKET.IO-ON EVENT ARGS &BODY BODY
which works just like DEFUN
except that
EVENT
specifies an event name called client-side, as string.
In order to give a more complete example, what follows is basically a "translation" of the [socket.io usage sample] (http://socket.io/#how-to-use) to hunchen.io:
(start (defparameter *acceptor* (make-instance 'websocket-acceptor)))
(define-socket.io-handler #'(lambda (message)
(declare (ignore message))))
(socket.io-on "connection" (session)
(declare (ignore session))
(socket.io-emit "news" '((:hello . "world")))
(socket.io-on "my other event" (data)
(log-message :debug data)))
(start (defparameter *acceptor* (make-instance 'websocket-acceptor)))
(define-socket.io-handler #'(lambda (message)
(declare (ignore message))))
(socket.io-on "connection" (session)
(declare (ignore session))
(socket.io-on "private message" (from msg)
(log-message :debug "I received a private message by ~a saying ~a" from msg))
(socket.io-on "disconnect" ()
(socket.io-emit "user disconnected")))
(start (defparameter *acceptor* (make-instance 'websocket-acceptor)))
(define-socket.io-handler #'(lambda (message)
(declare (ignore message))))
(socket.io-on "connection" (session)
(socket.io-on "set nickname" (name)
(setf (getf-session session :nickname) name)
(socket.io-emit "ready"))
(socket.io-on "msg" ()
(log-message :debug "Chat message by ~a" (getf-session session :nickname))))
TODO endpoints
var chat = io
.of('/chat')
.on('connection', function (socket) {
socket.emit('a message', {
that: 'only'
, '/chat': 'will get'
});
chat.emit('a message', {
everyone: 'in'
, '/chat': 'will get'
});
});
var news = io
.of('/news')
.on('connection', function (socket) {
socket.emit('item', { news: 'item' });
});
TODO volatile
io.sockets.on('connection', function (socket) {
var tweets = setInterval(function () {
getBieberTweet(function (tweet) {
socket.volatile.emit('bieber tweet', tweet);
});
}, 100);
socket.on('disconnect', function () {
clearInterval(tweets);
});
});
(start (defparameter *acceptor* (make-instance 'websocket-acceptor)))
(define-socket.io-handler #'(lambda (message)
(declare (ignore message))))
(socket.io-on "connection" (session)
(declare (ignore session))
(socket.io-on "ferret" (name)
(declare (ignore name))
"woot"))
TODO broadcasting
io.sockets.on('connection', function (socket) {
socket.broadcast.emit('user connected');
});
(socket.io-on "connection" (session)
(declare (ignore session))
(socket.io-on "message" ())
(socket.io-on "disconnect" ()))
Homepage: http://www.cliki.net/hunchen.io
Hacking: http://github.com/e-user/hunchen.io
Copyright (C) 2011 Alexander Kahl e-user@fsfe.org
This file is part of hunchen.io.
See COPYING for license information.