Hi, just for keeping the reference and cc: to duda mailing list.
On Sat, Sep 22, 2012 at 3:17 AM, Paul Read <[email protected]> wrote: > I ran the example: > > dudac/dudac -f -w duda-examples/001_hello_world/ > > and in my browser: > http://192.168.1.39:2001/hello/ > > And it worked :-) > > But how? > I can't see how asking for '/hello' causes the page to be displayed when the > command map->static references "cb_hello" - what is the 'cb_' > > How does the magic happen please? Let me explain in brief steps how it works internally: - When Monkey starts, it looks for the plugins.load configuration file. On that one it will catch up the duda plugin "monkey-duda.so", which is a shared library. - When Duda plugin is loaded, it looks for two configuration files, the first one is conf/plugins/duda/duda.conf, where it specify the location of the web services and packages. The second file is the virtual host file "conf/sites/default" where it specifies which web service must be loaded. You can see this under the section [WEB_SERVICE] - In technical terms, a Duda web service is a shared library loaded by the Duda plugin: Monkey -> Duda Plugin -> Duda Web Services * Now about the web service internals: Every web service must have a duda_main() function, when the web service is loaded, it performs a symbols lookup and invoke that function, this is done from duda.c:69 (duda_service_register()). But there is a trick here, duda_main is an expanded macro, when you type duda_main it's replaced by a different content by the compiler, refer to webservice.h:78 : #define duda_main() _duda_bootstrap(struct duda_api_objects *api) { /* API Objects */ monkey = api->monkey; map = api->map; msg = api->msg; ..... so from Duda core what really happens is to load the symbol referencing to _duda_bootstrap: service_init = (int (*)()) duda_load_symbol(ws->handler, "_duda_bootstrap"); so finally the service_init variable, its a pointer referencing the service function. so we invoke _duda_bootstrap() remotely through service_init(..); If you look at the API when mapping static URLS, you do something like this: map->static_add("/", "cb_hello"); what does static add, is to register in a linked list the URL to map and the callback function *name*. check that the parameters are simple strings. So from duda core when the HTTP request arrives, it checks the static URLs registered, it will find "/" associated to a "cb_hello" function name, so the proper way to invoke the callback is to have a prior reference to that function through a symbol lookup (made in duda.c:91) , e.g: static_cb->callback = duda_load_symbol(ws->handler, static_cb->cb_name); for short static_cb->cb_name contains "cb_hello", so that function is referenced in static_cb->callback. When the request arrives we just do static_cb->callback(); and that function in the web service is triggered. BTW, the "cb_" prefix is used just to reference a "callback" function, its not mandatory but we can consider it a good practice to prefix your callbacks functions with cb_ . In order to accomplish the callback stuff we need to do a mix of pointers to structs and functions so at the beginning it can be confusing... the good part is that it works properly. So please feel free to ask or send us your comments, cheers! > > -- > Paul > > http://www.readiescards.co.uk > > > _______________________________________________ > Monkey mailing list > [email protected] > http://lists.monkey-project.com/listinfo/monkey > -- Eduardo Silva http://edsiper.linuxchile.cl http://www.monkey-project.com _______________________________________________ Monkey mailing list [email protected] http://lists.monkey-project.com/listinfo/monkey
