sebpiq / rhizome

Web server for participative art performances and installations.
GNU General Public License v3.0
164 stars 13 forks source link

Document rhizome client and server classes and their public API #76

Open taylorbf opened 9 years ago

taylorbf commented 9 years ago

Hi again,

I wonder if there are plans, or if it's currently possible, to use rhizome as a submodule of a larger project. I.e., not installing it globally, but installing it as a dependency and being able to add something like this to a node script:

var rz = require('rhizome-server')
rz('config.js')

or

rz.start('config.js')

This may not be in your design goals, I am just checking in about it. Thanks, the currently workflow works great!!

sebpiq commented 9 years ago

Hi Ben!

Yes, it is definitely in my plans, and it is already possible. In fact personnally I am mostly using rhizome API instead of the command-line tool. However, the API is lower-level than simply rz.start('config.js'). At its heart, rhizome is really just a client - server library, that try to implement a unified interface over different protocols. Therefore, you are free to use those client / servers directly from, but I haven't really worked on exposing this API, and making it as easy as possible.

My plans for rhizome next are to clean all these server / clients, make them as consistent as possible, document their API better and make it really easy to use them.

For now, if you want to use them, you'll have to dive into the code a bit. You can maybe start by looking at the tests. But the basic design is that each server implements 2 classes Server and Connection (https://github.com/sebpiq/rhizome/blob/master/lib/core/server.js). And the other thing is that there is a global connection manager which all the server instances use to persist data, save connections and so on (https://github.com/sebpiq/rhizome/blob/master/lib/connections/ConnectionManager.js) ... Most of the rest is just protocol specific crap.

As an example of usage, here is what the server for Fields look like (notice that rhizome only handles websockets here. Even basic HTTP is handled by another library called express) :

#!/usr/bin/env node
var path = require('path')
  , debug = require('debug')('fields.main')
  , async = require('async')
  , express = require('express')
  , rhizome = require('./rhizome')

var staticDir = path.join(__dirname, 'dist')
  , httpServer, wsServer

// Code that will run if the module is main
if (require.main === module) {
  var config = require(path.join(process.cwd(), process.argv[2]))

  // Connection manager
  rhizome.connections.manager = new rhizome.connections.ConnectionManager({
    store: config.server.tmpDir
  })

  // HTTP server
  var app = express()
  httpServer = require('http').createServer(app)
  app.set('port', config.server.port)
  app.use(express.logger('dev'))
  app.use(express.bodyParser())
  app.use(express.methodOverride())
  app.use(app.router)
  app.use('/', express.static(staticDir))

  // Websocket server
  wsServer = new rhizome.websockets.Server({ serverInstance: httpServer })

  // Start servers
  async.parallel([
    rhizome.connections.manager.start.bind(rhizome.connections.manager),
    httpServer.listen.bind(httpServer, app.get('port')),
    wsServer.start.bind(wsServer)
  ], function(err) {
    if (err) throw err
    console.log('Fields running on port ' + config.server.port)
  })

}