Skip to content
Snippets Groups Projects
Commit f3038766 authored by Stephen R. van den Berg's avatar Stephen R. van den Berg
Browse files

SocketIO: Support creation of multiple Universes (Yes, we think BIG :-).

parent df509229
Branches
Tags
No related merge requests found
...@@ -77,10 +77,11 @@ private enum { ...@@ -77,10 +77,11 @@ private enum {
ICLIENTS=0, IEVENTS, IREADCB, ICLOSECB, IOPENCB ICLIENTS=0, IEVENTS, IREADCB, ICLOSECB, IOPENCB
}; };
// All Socket.IO nsps with connected clients class Universe {
private mapping(string: // All Socket.IO _nsps with connected clients in this universe.
array(multiset(.EngineIO.Socket)|mapping(string:multiset(function))|function)) final mapping(string: array(multiset(.EngineIO.Socket)|
nsps = ([]); mapping(string:multiset(function))|function))
_nsps = ([]);
//! @param _options //! @param _options
//! Optional options to override the defaults. //! Optional options to override the defaults.
...@@ -90,6 +91,8 @@ private mapping(string: ...@@ -90,6 +91,8 @@ private mapping(string:
//! @example //! @example
//! Sample minimal implementation of a SocketIO server farm: //! Sample minimal implementation of a SocketIO server farm:
//! //!
//!Protocols.SocketIO.Universe myuniverse;
//!
//!void echo(mixed id, function sendack, mixed ... data) { //!void echo(mixed id, function sendack, mixed ... data) {
//! id->write(data); //! id->write(data);
//! if (sendack) //! if (sendack)
...@@ -100,18 +103,19 @@ private mapping(string: ...@@ -100,18 +103,19 @@ private mapping(string:
//! httprequest(req); //! httprequest(req);
//!} //!}
//! //!
//!void httprequest(object req) //!void httprequest(object req) {
//!{ switch (req.not_query) //! switch (req.not_query) {
//! { case "/socket.io/": //! case "/socket.io/":
//! Protocols.SocketIO.Client client = Protocols.SocketIO.farm(req); //! Protocols.SocketIO.Client client = myuniverse.farm(req);
//! if (client) //! if (client)
//! client->write("Hello world!"); //! client->write("Hello world!");
//! break; //! break;
//! } //! }
//!} //!}
//! //!
//!int main(int argc, array(string) argv) //!int main(int argc, array(string) argv) {
//!{ Protocols.SocketIO.createnamespace("", echo); // Register root namespace //! myuniverse = Protocols.SocketIO.Universe(); // Create universe
//! myuniverse.createnamespace("", echo); // Register root namespace
//! Protocols.WebSocket.Port(httprequest, wsrequest, 80); //! Protocols.WebSocket.Port(httprequest, wsrequest, 80);
//! return -1; //! return -1;
//!} //!}
...@@ -124,17 +128,18 @@ final Client farm(Protocols.WebSocket.Request req, void|mapping _options) { ...@@ -124,17 +128,18 @@ final Client farm(Protocols.WebSocket.Request req, void|mapping _options) {
else else
_options = options; _options = options;
Protocols.EngineIO.Socket con = Protocols.EngineIO.farm(req, _options); Protocols.EngineIO.Socket con = Protocols.EngineIO.farm(req, _options);
return con && Client(con); return con && Client(this, con);
} }
//! Create a new or update an existing namespace. //! Create a new or update an existing namespace.
final void createnamespace(string namespace, final void createnamespace(string namespace,
void|function(mixed, function(mixed, mixed ...:void), mixed ...:void) read_cb, void|function(mixed, function(mixed, mixed ...:void), mixed ...:void)
read_cb,
void|function(mixed:void) close_cb, void|function(mixed:void) close_cb,
void|function(mixed:void) open_cb) { void|function(mixed:void) open_cb) {
array nsp = nsps[namespace]; array nsp = _nsps[namespace];
if (!nsp) if (!nsp)
nsps[namespace] = ({(<>), ([]), read_cb, close_cb, open_cb}); _nsps[namespace] = ({(<>), ([]), read_cb, close_cb, open_cb});
else { else {
nsp[IREADCB] = read_cb; nsp[IREADCB] = read_cb;
nsp[ICLOSECB] = close_cb; nsp[ICLOSECB] = close_cb;
...@@ -144,8 +149,8 @@ final void createnamespace(string namespace, ...@@ -144,8 +149,8 @@ final void createnamespace(string namespace,
//! Drop a namespace. //! Drop a namespace.
final void dropnamespace(string namespace) { final void dropnamespace(string namespace) {
array nsp = nsps[namespace]; array nsp = _nsps[namespace];
m_delete(nsps, namespace); m_delete(_nsps, namespace);
foreach (nsp[ICLIENTS];; Client client) foreach (nsp[ICLIENTS];; Client client)
if (client) if (client)
client.close(); client.close();
...@@ -156,7 +161,7 @@ final void dropnamespace(string namespace) { ...@@ -156,7 +161,7 @@ final void dropnamespace(string namespace) {
final int broadcast(string namespace, mixed ... data) { final int broadcast(string namespace, mixed ... data) {
Client client; Client client;
int cnt = 0; int cnt = 0;
array nsp = nsps[namespace]; array nsp = _nsps[namespace];
foreach (nsp[ICLIENTS];; client) foreach (nsp[ICLIENTS];; client)
cnt++, client.write(@data); cnt++, client.write(@data);
return cnt; return cnt;
...@@ -164,23 +169,23 @@ final int broadcast(string namespace, mixed ... data) { ...@@ -164,23 +169,23 @@ final int broadcast(string namespace, mixed ... data) {
//! //!
final int connected(string namespace) { final int connected(string namespace) {
array nsp = nsps[namespace]; array nsp = _nsps[namespace];
return sizeof(nsp[ICLIENTS]); return sizeof(nsp[ICLIENTS]);
} }
//! //!
final multiset clients(string namespace) { final multiset clients(string namespace) {
array nsp = nsps[namespace]; array nsp = _nsps[namespace];
return nsp[ICLIENTS]; return nsp[ICLIENTS];
} }
//! Use the indices to get a list of the nsps in use. //! Use the indices to get a list of the _nsps in use.
final mapping namespaces() { final mapping namespaces() {
return nsps; return _nsps;
} }
private multiset getlisteners(string namespace, string event) { private multiset getlisteners(string namespace, string event) {
mapping events = nsps[namespace][IEVENTS]; mapping events = _nsps[namespace][IEVENTS];
multiset listeners = events[event]; multiset listeners = events[event];
if (!listeners) if (!listeners)
events[event] = listeners = (<>); events[event] = listeners = (<>);
...@@ -200,9 +205,11 @@ final void off(string namespace, string event, ...@@ -200,9 +205,11 @@ final void off(string namespace, string event,
event_cb) { event_cb) {
getlisteners(namespace, event)[event_cb] = 0; getlisteners(namespace, event)[event_cb] = 0;
} }
}
//! Runs a single Socket.IO session. //! Runs a single Socket.IO session.
class Client { class Client {
private Universe universe;
//! //!
string namespace=""; string namespace="";
...@@ -243,7 +250,7 @@ class Client { ...@@ -243,7 +250,7 @@ class Client {
} }
private void fetchcallbacks() { private void fetchcallbacks() {
array nsp = nsps[namespace]; array nsp = universe._nsps[namespace];
if (nsp) { if (nsp) {
read_cb = nsp[IREADCB]; read_cb = nsp[IREADCB];
close_cb = nsp[ICLOSECB]; close_cb = nsp[ICLOSECB];
...@@ -354,7 +361,7 @@ class Client { ...@@ -354,7 +361,7 @@ class Client {
send(ACK, data, cackid); send(ACK, data, cackid);
}; };
if (sizeof(curevent) && stringp(curevent[0])) { if (sizeof(curevent) && stringp(curevent[0])) {
multiset listeners = nsps[namespace][IEVENTS][curevent[0]]; multiset listeners = universe._nsps[namespace][IEVENTS][curevent[0]];
if (listeners && sizeof(listeners)) { if (listeners && sizeof(listeners)) {
function(mixed ...:void) cachesendackcb = cackid >= 0 && sendackcb; function(mixed ...:void) cachesendackcb = cackid >= 0 && sendackcb;
function(mixed, function(mixed, mixed ...:void), string, function(mixed, function(mixed, mixed ...:void), string,
...@@ -383,7 +390,7 @@ class Client { ...@@ -383,7 +390,7 @@ class Client {
} }
private void unregister() { private void unregister() {
array nsp = nsps[namespace]; array nsp = universe._nsps[namespace];
if (nsp) if (nsp)
nsp[ICLIENTS][this] = 0; nsp[ICLIENTS][this] = 0;
} }
...@@ -416,9 +423,9 @@ class Client { ...@@ -416,9 +423,9 @@ class Client {
case ERROR: case ERROR:
SUSERERROR(data); // Pass error up SUSERERROR(data); // Pass error up
case CONNECT: case CONNECT:
if (nsps[data]) { if (universe._nsps[data]) {
unregister(); // Old namespace unregister(); // Old namespace
nsps[namespace = data][ICLIENTS][this] = 1; universe._nsps[namespace = data][ICLIENTS][this] = 1;
fetchcallbacks(); fetchcallbacks();
state = RUNNING; state = RUNNING;
send(CONNECT, namespace); // Confirm namespace send(CONNECT, namespace); // Confirm namespace
...@@ -468,7 +475,8 @@ class Client { ...@@ -468,7 +475,8 @@ class Client {
closedown(); closedown();
} }
protected void create(Protocols.EngineIO.Socket _con) { protected void create(Universe _universe, Protocols.EngineIO.Socket _con) {
universe = _universe;
conn = _con; conn = _con;
fetchcallbacks(); fetchcallbacks();
conn.set_callbacks(recv, closedown); conn.set_callbacks(recv, closedown);
...@@ -481,7 +489,7 @@ class Client { ...@@ -481,7 +489,7 @@ class Client {
switch (type) { switch (type) {
case 'O': case 'O':
res = sprintf(DRIVERNAME"(%s.%d,%d,%d)", res = sprintf(DRIVERNAME"(%s.%d,%d,%d)",
sid, protocol, state, sizeof(nsps)); sid, protocol, state, sizeof(universe._nsps));
break; break;
} }
return res; return res;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment