Main  /  Edit version 9  /  Edit version 10  /   /  Users Area

Difference "cppcms::worker_thread & cppcms::application" ver. 9 versus ver. 10

Content:

## Table of Contents
- [Roles](#roles)
- [Constructors](#ctor)
- [Public Members](#memb)
- [Public Member Functions](#membf)
- [HTTP Headers](#hdr)
- [Localization](#loc)
- [Templates rendering](#rend)
- [cppcms::application member functions](#application)
- [Virtual Member functions](#vmemb)
- [Public Template Member Functions](#templmeb)
## <span id="roles"></span>Roles
`worker_thread` and `application` are very similar classes that gives user similar APIs but they have important differences:
`worker_thread` has single instance in each worker thread or process, it is usually not used directly, but it is referenced by several `application` classes.
In many cases, we need to have more then one application or sub application in our process (for example wiki and forum or users panel and administration panel).
All these application share same controls like access to cache and sessions, access for HTTP requests --- all these stored in `worker_thread` class.
In terms of API, both classes are very similar with the difference that `worker_thread` stores actual data and `application` stores references to this data in `worker_thread`.
In most of cases developers should derive their own classes
from `cppcms::application` and not from `cppcms::worker_thread`.
## <span id="ctor"></span>Constructors
worker_thread(manager const &s);
application(worker_thread &w);
`worker_thread` and `application` constructors should receive a reference to `manager` and primary `worker_thread`.
For example:
class my_application : public application {
my_application(worker_thread &w) : application(w) {
...
## <span id="memb"></span>Public Members
### cppcms::application
worker_thread &worker;
url_parser &url;
manager const &app;
cgicc::Cgicc *&cgi;
cgicc::CgiEnvironment const *&env;
cgicc_connection *&cgi_conn;
cache_iface &cache;
session_interface &session;
ostream &cout;
boost::signal<void()> &on_start;
boost::signal<void()> &on_end;
### cppcms::worker\_thread
url_parser url;
manager const &app;
cgicc::Cgicc *cgi;
cgicc::CgiEnvironment const *env;
cgicc_connection *cgi_conn;
cache_iface cache;
session_interface session;
ostream cout;
boost::signal<void()> on_start;
boost::signal<void()> on_end;
### Description
- **`url_parser url`**
It is a class responsible on binding various handlers
to different requested url. For example:
url.add("^/test$",&app::test,this);
See [`cppcms::url_parser`](/wikipp/en/page/ref_cppcms_url_parser) for reference.
- **`manager const &app`** -- access to [`cppcms::manager`](/wikipp/en/page/ref_cppcms_manager) class. Usually used to fetch configuration values. For example:
int num=app.config.ival("my_app.number");
- **`cgicc::Cgicc *cgi`** -- access to [`cgicc::Cgicc`](http://www.gnu.org/software/cgicc/doc/classcgicc_1_1Cgicc.html) class of cgicc library that gives you a content of HTTP query.
It is usually used together with form processing:
some_content c;
c.some_form.load(*cgi);
- **`cgicc::CgiEnvironment const *env`** -- environment of cgicc query. See [`cgicc::CgiEnvironment`](http://www.gnu.org/software/cgicc/doc/classcgicc_1_1CgiEnvironment.html)
- **`cgicc_connection *cgi_conn`** --- access to low level CGI API. Input stream, output stream environment variables.
Generally it should be used only in case we need access to some CGI environment variable unsupported by cgicc. For example:
string encodings=cgi_conn->env("ACCEPT_ENCODING");
- **`cache_iface cache`** -- access to cache API. See: [`cache_iface`](/wikipp/en/page/ref_cppcms_cache_iface)
- **`session_interface session`** -- access to sessions API. See: [`session_interface`](/wikipp/en/page/ref_cppcms_session_iface)
- **`ostream cout`** --- the stream for output content of the cgi process (without headers). It is generally used via templates system, however it can be used directly for creating HTML or any other output content.
For example, create csv:
set_header(new HTTPContentHeader("text/csv"));
cout<<"n,n!"<<endl;
cout<<"0, 1"<<endl;
cout<<"1, 1"<<endl;
cout<<"2, 2"<<endl;
cout<<"3, 6"<<endl;
- **`boost::signal<void()> on_start, on_end`** --- these are the signals that application can connect itself in order to perform certain tasks when new query comes, independently from URL.
Various application running in same thread may attach
many signals.
For example:
class my_app: public application {
int user_id;
string user_name;
void start()
{
if(session.is_set("user_id")) {
user_id=session.get<int>("user_id");
user_name=fetch_user_name(user_id);
}
else {
user_id=-1;
user_name="visitor";
}
}
void end()
{ // Cleanup all user data
user_id=0;
user_name.clear();
}
...
my_app()
{
on_start.connect(bind(&start,this));
on_end.connect(bind(&end,this));
...
}
**Note:** callbacks connected to `on_end` should never throw -- think of them as of destructors.
## <span id="membf"></span>Public Member Functions
### <span id="hdr"></span>HTTP Headers
- **`void set_header(cgicc::HTTPHeader *h)`** -- set newly created HTTP Header.
Notes:
1. Default header is `cgicc::HTTPHTMLHeader`.
2. It removes previous header and all cookies associated with it. Thus, always set header and then set cookies.
3. The pointer to header is freed by an application.
For example:
set_header(new HTTPContentHeader("text/csv"));
See [cgicc::HTTPHeader](http://www.gnu.org/software/cgicc/doc/classcgicc_1_1HTTPHeader.html) for details.
- **`void set_cookie(cgicc::HTTPCookie const &c)`** --- set HTTP Cookie to current header.
See: [cgicc::HTTPCookie](http://www.gnu.org/software/cgicc/doc/classcgicc_1_1HTTPCookie.html) for details of cookies creation.
- **`cgicc::HTTPHeader &header()`** -- return current header.
- **`void add_header(string s)`** -- add general header. For example:
add_header("X-Sendfile: " + filename);
CgiCC API does not allow rendering several headers together, thus -- `add_header(string)` removes this limitation. For example:
add_header("Status: 302 Found");
set_header(new HTTPRedirectHeader(new_location));
- **`void set_user_io()`** -- allows user to write directly to output stream instead of internal buffer.
Calling this functions forces saving all session
data and all headers are immediately written
to the output stream. Thus, updating session data
or changing headers would not take an effect.
It can be used for generating big output that
should not be saved in internal buffers and compressed.
or changing headers would not take an effect after this
function is called.
__Note:__ You should use output stream from `cgi_conn`
instead of ordinary `cout` member of `worker_thread`
for output.
This function can be used for generating big output that
should not be saved in internal buffers and compressed.
For example, streaming of image::
ifstream file("big.png");
set_header(new cgicc::HTTPContentHeader("image/png"));
set_user_io();
ostream &cout=cgi_conn->cout();
for(;;) {
file.read(&buffer.front(),1024);
cout.write(&buffer.front(),file.gcount());
if(file.eof())
break;
}
file.close();
### <span id="loc"></span>Localization
Setting language dynamically:
- **`void set_lang()`** -- Set default application language.
- **`void set_lang(string const &)`** -- Set application language. This call affects all other calls of `gettext()`, `ngettext()` and language of template rendering.
Translating strings:
- **`char const *gettext(char const *s)`** -- translate string "s".
- **`char const *ngettext(char const *s,char const *p,int n)`** -- translate single/plural form of string for `n`.
_Note:_ In contrary to GNU gettext library, these functions are thread safe --- you can use different languages in different threads safely.
Working with different domain:
- **`transtext::trans const *domain_gettext(string const &d)`** -- returns pointer to gettext dictionary for specific domain. `transtext::trans` has two public functions important to user: gettext and ngettext with same signatures as above.
For example:
transtext::trans const *tr=domain_gettext("views");
string username=tr->gettext("username");
This function has no effect on current gettext dictionary.
### <span id="rend"></span>Templates rendering
**Setting skins**
void use_template(string s="");
Set template. If no specified, default is used. For example:
if(session.is_set("skin"))
use_template(session["skin"]);
**Rendering output**
void render(string teml,base_content &c);
void render(string view,string teml,base_content &c);
void render(string teml,base_content &c,ostream &o);
void render(string view,string teml,base_content &c,ostream &o);
Render specific function `templ` using content `c`. If `view` specified, render using view `view` instead of default.
If `ostream &o` specified render template to `o` instead of cout. The recent is useful to create partial renderings and caching them. For example:
ostringstream tmp;
render("sidebar",content,tmp);
cache.store_frame("sidebar",tmp.str());
## <span id="application"></span>cppcms::application member functions
### <span id="vmemb"></span>Virtual Member functions
**Note:** these functions are used only in `cppcms::application` class where user can override default functionality. They does not exist in `worker_thread` or have different semantics.
- **`virtual void on_404()`** --- default handler that is called in case of URL that does not match any given pattern.
You may display your own page there or redirect to general correct url.
- **`virtual void main()`** --- this is the main function. It has following default implementation:
on_start();
if(url.parse()<0) {
on_404();
}
on_end();
If you decide to override this function, don't forget ti call `on_start` and `on_end` semantics. For example, you can try to handle there sql connection errors:
on_start();
for(i=0;i<2;i++) {
try {
if(url.parse()<0) {
on_404();
}
break;
}
catch(sql_connection_error &e)
{
if(i==0)
sql.reconnect();
else
no_connection_page();
}
}
on_end();
**Notes:** Only **one** application class may override it's `main()` because only one main function is called. Rest applications working in same thread are called using url bindings.
### <span id="templmeb"></span>Public Template Member Functions
These functions are used for easier connection of
SQL libraries to an application. Assuming you have persistent SQL connection per thread.
These functions implemented as template functions in order
to prevent linking with specific libraries.
#### SOCI
template<typename SQL>
void soci_load(SQL &sql)
Connect to SQL database using [SOCI](http://soci.sourceforge.net/).
_CppCMS Configuration parameters:_
- `soci.conn` soci connection string calling: `sql.open(conn);`
- `soci.driver`, `soci.params` -- connect to soci calling: `sql.open(driver,params);`
#### DbiXX
template<typename SQL>
void dbixx_load(SQL &sql);
Connects to database using dbixx library, it uses following parameters:
- `dbixx.driver` --- the SQL driver used for dbixx, for example "sqlite3".
All other parameters are taken from configuration using prefix given in `dbixx.driver`. For example:
dbixx.driver="sqlite3"
sqlite3.dbname="wikipp.db"
sqlite3.sqlite3_dbdir="./db/"
Refer to [libdbi-drivers](http://libdbi-drivers.sourceforge.net/docs.html) documentation pages for setting up correct parameters.

About

CppCMS is a web development framework for performance demanding applications.

Support This Project

SourceForge.net Logo

Поддержать проект

CppCMS needs You


Navigation

Main Page


Valid CSS | Valid XHTML 1.0