Http = require('http')
Url = require('url')
Path = require('path')Http = require('http')
Url = require('url')
Path = require('path')WS = require('ws')
Connect = require('connect')
Ecstatic = require('ecstatic')RequestHandler = require('./RequestHandler')
SocketHandler = require('./SocketHandler')
Container = require('./ServerContainer')
InitStore = require('./InitStore')
JWT = require('./JWT')
PageMap = require('../Shared/PageMap')Handles HTTP and WebSocket connections from client
Initial request from the client is HTTP GET of some url. The Server delegates this request to RequestHandler, which in turn uses PageMap to find a page in $args.pages matching a route name in $args.map. The page loads the data and views it needs and then renders itself and sends the result back to the client. It also stores that data and a view id_map for later use by the SocketHandler.
When the Client subsequently connects via EngineIO/WebSocket, a instance of SocketHandler is created to handle this persistent connection with the client. The client is immediately sent an initializion payload consisting of the stored data mentioned above. This is done in order to create an instance of the page on the client and sync it with the view hierarchy previously rendered on the server prior to attaching event/behavior handlers in the view.
At this point, all subsequent communication is done via JSON over the socket connection, and all rendering happens in the client.
class Servername : name of the app/server
map : map of routes to pages
messages : class that will be instantiated to handle page request messages
models : Server side models used
jwt_secret : JSON web token secret
favicon : path for user’s favicon
static : Should have path and filepath keys mapping to the url path and filesystem path for static assets
container : Override the default container used for pages. Default implementation is Container If overriding, you must set container on server as well.
request : Override request handler
socket : Override socket handler
logo_url : Url for a site logo
constructor : (args = {})->
required_args = ['name', 'map', 'messages', 'jwt_secret', 'favicon']
for arg in required_args
unless args[arg]
throw new Error("diso.core.Server: Missing argument #{arg}")
jwt_secret = args.jwt_secret
map = args.map
favicon = args.favicon
@_name = args.name
@_models = args.models
Messages = args.messages
@_messages = new Messages()optional args
static_config = args.static
if ('request' of args)
RequestHandler = args.request
if ('socket' of args)
SocketHandler = args.socket
container = if ('container' of args)
args.container
else
new Container(
logo_url : args.logo_url
site_name : args.name
)
init_store_config = if ('init_store' of args)
args.init_store
else
{ type : 'memory' }
@_init_store = InitStore.create(init_store_config) _static = null
if static_config1) Static asset handling
_static = Ecstatic(
root : static_config.filepath
baseDir : static_config.path
handleError : false
)2) favicon
if favicon
favicon = Connect.favicon(favicon)3) body parser
body_parser = Connect.bodyParser()4) JWT
@_jwt = new JWT(
secret : jwt_secret
models : @_models
) @_page_map = new PageMap(
map : map
models : @_models
)6) RequestHandler answers initial HTTP requests
request_handler = new RequestHandler(
init_store : @_init_store
container : container
)Create the connect middleware pipeline
connect = Connect()
if _static
connect.use(_static)
if favicon
connect.use(favicon)
connect
.use(body_parser)
.use(@_jwt)
.use(@_page_map)
.use(request_handler)create the server
@_http_server = Http.createServer(connect)Listen for HTTP connections on port number passed as argument and setup the WebSocket listener
port : port to listen on
listen : (port)->
@_http_server.listen(port)
@_socket_server = new WS.Server(server : @_http_server)
@_socket_server.on('connection', @_onSocketConnection) _onSocketConnection : (socket)=>
new SocketHandler(
socket : socket
messages : @_messages
models : @_models
jwt : @_jwt
init_store : @_init_store
page_map : @_page_map
)
module.exports = Server