1062 lines
90 KiB
HTML
1062 lines
90 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||
<html>
|
||
|
||
<head>
|
||
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
|
||
<title>QxOrm : C++ Qt ORM Object Relational Mapping database library - QxEntityEditor : C++ Qt entities graphic
|
||
editor (data model designer and source code generator)</title>
|
||
<link rel='stylesheet' type='text/css' href='./resource/qxorm_style.css'>
|
||
<script type="text/javascript" src="./resource/jquery.min.js"></script>
|
||
<script type="text/javascript" src="./resource/qxorm_script.js"></script>
|
||
</head>
|
||
|
||
<body>
|
||
<table border="0" style="width: 80%" align="center">
|
||
<col>
|
||
<col>
|
||
<col>
|
||
<col>
|
||
<col>
|
||
<tbody>
|
||
<tr>
|
||
<td><a href="./home.html"><img alt="QxOrm" src="./resource/logo_qxorm_and_qxee.png" align="left"
|
||
border="0"></a></td>
|
||
<td align="right" style="vertical-align:bottom">
|
||
<div id="qx_search">
|
||
<gcse:search></gcse:search>
|
||
</div>
|
||
</td>
|
||
<td width="15"></td>
|
||
<td align="right" style="vertical-align:bottom">
|
||
<img alt="Windows" src="./resource/logo_windows.gif" width="35" height="35">
|
||
<img alt="Linux" src="./resource/logo_linux.gif" width="35" height="35">
|
||
<img alt="Macintosh" src="./resource/logo_mac.gif" width="35" height="35">
|
||
</td>
|
||
<td width="70"><img alt="C++" src="./resource/logo_cpp.gif" width="50" height="50" align="right"></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<hr style="width: 80%" align="center" size="1" color="#100D5A">
|
||
<table border="0" style="width: 80%" align="center">
|
||
<col>
|
||
<col>
|
||
<col>
|
||
<col>
|
||
<col>
|
||
<col>
|
||
<tbody>
|
||
<tr>
|
||
<td align="center"><a href="./home.html" class="btn_nav">Home</a></td>
|
||
<td align="center"><a href="./download.html" class="btn_nav">Download</a></td>
|
||
<td align="center"><a href="./quick_sample.html" class="btn_nav">Quick sample</a></td>
|
||
<td align="center" onmouseover="showHideElementById('menu_tuto', true);"
|
||
onmouseout="showHideElementById('menu_tuto', false);">
|
||
<a href="./tutorial.html" class="btn_nav">Tutorial (4)</a>
|
||
<table class="table_menu_tuto">
|
||
<tbody>
|
||
<tr>
|
||
<td>
|
||
<div id="menu_tuto" class="div_menu_tuto">
|
||
<a href="./tutorial_3.html" class="btn_sub_menu">install QxOrm</a><br />
|
||
<a href="./tutorial.html" class="btn_sub_menu">qxBlog</a><br />
|
||
<a href="./tutorial_2.html" class="btn_sub_menu">qxClientServer</a><br />
|
||
<a href="./tutorial_4.html" class="btn_sub_menu">QxEntityEditor videos</a>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</td>
|
||
<td align="center" onmouseover="showHideElementById('menu_manual', true);"
|
||
onmouseout="showHideElementById('menu_manual', false);">
|
||
<a href="./manual.html" class="btn_nav">Manual (2)</a>
|
||
<table class="table_menu_manual">
|
||
<tbody>
|
||
<tr>
|
||
<td>
|
||
<div id="menu_manual" class="div_menu_manual">
|
||
<a href="./manual.html" class="btn_sub_menu">QxOrm manual</a><br />
|
||
<a href="./manual_qxee.html" class="btn_sub_menu">QxEntityEditor manual</a><br />
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</td>
|
||
<td align="center"><a href="./link.html" class="btn_nav">Forum</a></td>
|
||
<td align="center"><a href="./customer.html" class="btn_nav">Our customers</a></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<hr style="width: 80%" align="center" size="1" color="#100D5A">
|
||
<table border="0" style="width: 80%" align="center">
|
||
<col>
|
||
<col>
|
||
<col>
|
||
<col>
|
||
<col>
|
||
<col>
|
||
<tbody>
|
||
<tr>
|
||
<td align="left" valign="top">
|
||
<font size="2" class="txt_with_shadow">QxOrm >> Tutorial >> qxClientServer</font>
|
||
</td>
|
||
<td align="right" valign="top">
|
||
<table cellspacing="0" cellpadding="1">
|
||
<col>
|
||
<col>
|
||
<tbody>
|
||
<tr>
|
||
<td align="right" valign="top">
|
||
<font size="2" class="txt_with_shadow">Current version : </font>
|
||
</td>
|
||
<td align="left" valign="top">
|
||
<font size="2" class="txt_with_shadow">QxOrm 1.5.0 - <a href="../doxygen/index.html"
|
||
target="_blank">QxOrm library online class documentation</a> - <a
|
||
href="https://github.com/QxOrm/QxOrm" target="_blank">GitHub</a></font>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td align="right" valign="top">
|
||
<font size="2" class="txt_with_shadow"></font>
|
||
</td>
|
||
<td align="left" valign="top">
|
||
<font size="2" class="txt_with_shadow">QxEntityEditor 1.2.8</font>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</td>
|
||
<td width="10px"></td>
|
||
<td width="40px" height="30px"><a href="../qxorm_fr/tutorial_2.html"><img alt="Version fran<61>aise du site"
|
||
src="./resource/FR.png" width="40" height="30" border="0"></a></td>
|
||
<td width="40px" height="30px"><a href="../qxorm_en/tutorial_2.html"><img alt="Web site english version"
|
||
src="./resource/GB.png" width="40" height="30" border="0"></a></td>
|
||
<td width="40px" height="30px"><a href="http://sites.google.com/site/qxormpostgres/" target="_blank"><img
|
||
alt="" src="./resource/ES.png" width="40" height="30" border="0"></a></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<table border="1" frame="vsides" rules="cols" style="width: 80%" align="center" cellpadding="6" bgcolor="#F2F2F4">
|
||
<col>
|
||
<tbody>
|
||
<tr>
|
||
<td align="justify">
|
||
<table border="0" cellpadding="4">
|
||
<col>
|
||
<col>
|
||
<tbody>
|
||
<tr>
|
||
<td>
|
||
<font class="txt_with_shadow" color="#0B0B61" size="4"><i>Select a tutorial : </i></font>
|
||
</td>
|
||
<td align="left">
|
||
<a href="./tutorial.html" class="btn_tuto">Tuto n<>1 : qxBlog</a>
|
||
<a href="./tutorial_2.html" class="btn_tuto_selected">Tuto n<>2 : qxClientServer</a>
|
||
<a href="./tutorial_3.html" class="btn_tuto">Tuto n<>3 : install QxOrm</a>
|
||
<a href="./tutorial_4.html" class="btn_tuto">Tuto n<>4 : video QxEntityEditor</a>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<hr style="width: 100%" align="center" size="1" color="#100D5A">
|
||
<br>
|
||
<table border="0" style="width: 100%" align="center">
|
||
<col>
|
||
<col>
|
||
<tbody>
|
||
<tr>
|
||
<td>The main purpose of <b>qxClientServer</b> tutorial is to explain how <b>QxService</b> module
|
||
of <b>QxOrm</b> library works.<br>
|
||
<b>QxService</b> module provides an easy and powerful way to create <b>C++ application
|
||
server</b> (<i>services</i> concept with <i>request</i> from client and <i>reply</i> from
|
||
server).<br>
|
||
<b>qxClientServer</b> project source code is available in the directory
|
||
<i>./test/qxClientServer/</i>.<br>
|
||
It is recommended to read <b>qxBlog</b> tutorial before reading this article, in particular
|
||
<b>QxOrm</b> mapping function by class : <u><i>void
|
||
qx::register_class<T>(...)</i></u>.<br>
|
||
<br>
|
||
<b>Note :</b> to enable <b>QxService</b> module (required to build <b>qxClientServer</b>
|
||
tutorial source code), it is necessary to define <b>_QX_ENABLE_QT_NETWORK</b> compilation
|
||
option in <i>QxOrm.pri</i> configuration file.
|
||
For more details about compilation options, <a href="./manual.html#manual_220">please read
|
||
the manual (user guide) of QxOrm library</a>.
|
||
<br><br>
|
||
<b>qxClientServer</b> tutorial contains 2 exec and a service layer :
|
||
<ul>
|
||
<li><i>qxServer</i> : C++ application server with a GUI to configure server and a field to
|
||
display last transaction between client and server.</li>
|
||
<li><i>qxClient</i> : GUI with buttons to execute some requests to server and to call
|
||
services.</li>
|
||
<li><i>qxService</i> : the service layer, server and client share the same service layer
|
||
to transfer data and call services.</li>
|
||
</ul>
|
||
<b>qxClientServer</b> tutorial step by step :
|
||
<ul>
|
||
<li><a href="#tuto_10">1- Server GUI : <i>qxServer</i></a>
|
||
<ul>
|
||
<li><a href="#tuto_101">1.1- File description <i>main_dlg.h</i></a></li>
|
||
<li><a href="#tuto_102">1.2- File description <i>main_dlg.cpp</i>, method
|
||
<i>init()</i></a></li>
|
||
<li><a href="#tuto_103">1.3- File description <i>main_dlg.cpp</i>, method
|
||
<i>loadServices()</i></a></li>
|
||
<li><a href="#tuto_104">1.4- File description <i>main_dlg.cpp</i>, method
|
||
<i>onClickStartStop()</i></a></li>
|
||
<li><a href="#tuto_105">1.5- File description <i>main_dlg.cpp</i>, methods
|
||
<i>onError()</i> and <i>onTransactionFinished()</i></a></li>
|
||
<li><a href="#tuto_106">1.6- Result with <i>qxServer</i> project</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#tuto_20">2- Service layer : <i>qxService</i></a>
|
||
<ul>
|
||
<li><a href="#tuto_201">2.1- First service : retrieve current date-time from
|
||
server</a></li>
|
||
<li><a href="#tuto_202">2.2- File description <i>server_infos.h</i></a></li>
|
||
<li><a href="#tuto_203">2.3- File description <i>server_infos.cpp</i></a></li>
|
||
<li><a href="#tuto_204">2.4- Second service : work with a persistent class</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#tuto_30">3- Client GUI : <i>qxClient</i></a>
|
||
<ul>
|
||
<li><a href="#tuto_301">3.1- Method description <i>onClickBtnDateTime()</i></a></li>
|
||
<li><a href="#tuto_302">3.2- Method description <i>onClickBtnDateTimeAsync()</i></a>
|
||
</li>
|
||
<li><a href="#tuto_303">3.3- Method description <i>onClickBtnAddUser()</i></a></li>
|
||
<li><a href="#tuto_304">3.4- Method description <i>onClickBtnGetAllUsers()</i></a>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</td>
|
||
<td width="200" align="center" valign="top"><a href="./resource/qt_ambassador_logo.png"
|
||
target="_blank"><img alt="qt_ambassador" src="./resource/qt_ambassador_logo_150x150.png"
|
||
width="150" height="150" border="0"></a><br>
|
||
<b>
|
||
<font size="2">QxOrm library has been accepted into the <a
|
||
href="http://forum.qt.io/category/24/qt-ambassador-program" target="_blank">Qt
|
||
Ambassador Program</a></font>
|
||
</b>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<br>
|
||
<img alt="gui_qxClientServer" src="./resource/gui_qxClientServer.jpg" width="1056" height="727"
|
||
style="border:0px solid #100D5A; border-color:#100D5A;">
|
||
<br><br>
|
||
<b>Note :</b> for more information about socket, thread, network, etc... <b>Qt</b> website provides
|
||
tutorials about <a href="http://doc.qt.io/qt-5/qtnetwork-index.html" target="_blank"><i>QtNetwork</i></a>
|
||
module :
|
||
<ul>
|
||
<li><a href="http://doc.qt.io/qt-5/qtnetwork-fortuneclient-example.html" target="_blank"><i>Fortune
|
||
Client Example</i></a></li>
|
||
<li><a href="http://doc.qt.io/qt-5/qtnetwork-blockingfortuneclient-example.html"
|
||
target="_blank"><i>Blocking Fortune Client Example</i></a></li>
|
||
<li><a href="http://doc.qt.io/qt-5/qtnetwork-fortuneserver-example.html" target="_blank"><i>Fortune
|
||
Server Example</i></a></li>
|
||
<li><a href="http://doc.qt.io/qt-5/qtnetwork-threadedfortuneserver-example.html"
|
||
target="_blank"><i>Threaded Fortune Server Example</i></a></li>
|
||
</ul>
|
||
<br>
|
||
<b><a name="tuto_10"><u>
|
||
<font color="#100D5A">1- Server GUI : <i>qxServer</i></font>
|
||
</u></a></b>
|
||
<br><br>
|
||
<i>qxServer</i> contains only 1 window : GUI has been designed with <b>Qt Designer</b> tool of Qt
|
||
library.<br>
|
||
The main purpose of this window is to display to user the last transaction between client and server, and
|
||
to configure some server parameters.<br>
|
||
For a real project (a production software), it is strongly recommended to provide a log system instead of
|
||
a GUI.<br>
|
||
A minimal user interface (or no user interface) is the optimal solution for an application server.<br>
|
||
<i>main_dlg.h</i> and <i>main_dlg.cpp</i> files implements <i>qxServer</i> GUI :<br>
|
||
<br>
|
||
<a name="tuto_101"><u>
|
||
<font color="#100D5A">1.1- File description <i>main_dlg.h</i></font>
|
||
</u></a>
|
||
<br><br>
|
||
<table border="1" bgcolor="#FFFFFF">
|
||
<col>
|
||
<tbody>
|
||
<tr>
|
||
<td title="main_dlg.h">
|
||
<pre><span class="pre">#ifndef _QX_SERVER_MAIN_DLG_H_
|
||
#define _QX_SERVER_MAIN_DLG_H_
|
||
|
||
#include "../qt/ui/include/ui_qxServer.h"
|
||
</span><span class="keyword">
|
||
class</span> main_dlg<span class="operator"> :</span><span class="keyword"> public</span> QWidget<span class="operator">,</span><span class="keyword"> private</span> Ui<span class="operator">::</span>dlgServer<span class="operator">
|
||
{</span> Q_OBJECT<span class="keyword">
|
||
|
||
private</span><span class="operator">:</span>
|
||
|
||
qx<span class="operator">::</span>service<span class="operator">::</span>QxThreadPool_ptr m_pThreadPool<span class="operator">;</span><span class="comment"> // Server thread pool to receive all requests
|
||
</span><span class="keyword">
|
||
public</span><span class="operator">:</span>
|
||
|
||
main_dlg<span class="operator">(</span>QWidget<span class="operator"> *</span> parent<span class="operator"> =</span> NULL<span class="operator">) :</span> QWidget<span class="operator">(</span>parent<span class="operator">),</span> Ui<span class="operator">::</span>dlgServer<span class="operator">() {</span> main_dlg<span class="operator">::</span>init<span class="operator">(); }</span><span class="keyword">
|
||
virtual</span><span class="operator"> ~</span>main_dlg<span class="operator">() { ; }</span><span class="keyword">
|
||
|
||
private</span><span class="operator">:</span><span class="type">
|
||
|
||
void</span> init<span class="operator">();</span><span class="type">
|
||
void</span> loadServices<span class="operator">();</span><span class="keyword">
|
||
|
||
private</span> Q_SLOTS<span class="operator">:</span><span class="type">
|
||
|
||
void</span> onClickStartStop<span class="operator">();</span><span class="type">
|
||
void</span> onCboIndexChanged<span class="operator">(</span><span class="type">int</span> index<span class="operator">);</span><span class="type">
|
||
void</span> onError<span class="operator">(</span><span class="keyword">const</span> QString<span class="operator"> &</span> err<span class="operator">,</span> qx<span class="operator">::</span>service<span class="operator">::</span>QxTransaction_ptr transaction<span class="operator">);</span><span class="type">
|
||
void</span> onServerIsRunning<span class="operator">(</span><span class="type">bool</span> bIsRunning<span class="operator">,</span> qx<span class="operator">::</span>service<span class="operator">::</span>QxServer<span class="operator"> *</span> pServer<span class="operator">);</span><span class="type">
|
||
void</span> onTransactionFinished<span class="operator">(</span>qx<span class="operator">::</span>service<span class="operator">::</span>QxTransaction_ptr transaction<span class="operator">);
|
||
|
||
};</span><span class="pre">
|
||
|
||
#endif // _QX_SERVER_MAIN_DLG_H_</span></pre>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<br>
|
||
<i>m_pThreadPool</i> variable of <i>qx::service::QxThreadPool_ptr</i> type contains application server
|
||
engine.<br>
|
||
<b>QxOrm</b> library manages all the logical : thread, request-reply, serialization, call services,
|
||
etc...<br>
|
||
<i>init()</i> method initializes default parameters of application server, connects <b>SIGNAL-SLOT</b>
|
||
events and runs automaticaly the server.<br>
|
||
<br>
|
||
<a name="tuto_102"><u>
|
||
<font color="#100D5A">1.2- File description <i>main_dlg.cpp</i>, method <i>init()</i></font>
|
||
</u></a>
|
||
<br><br>
|
||
<table border="1" bgcolor="#FFFFFF">
|
||
<col>
|
||
<tbody>
|
||
<tr>
|
||
<td title="main_dlg::init()">
|
||
<pre><span class="type">void</span> main_dlg<span class="operator">::</span>init<span class="operator">()
|
||
{</span>
|
||
setupUi<span class="operator">(</span><span class="keyword">this</span><span class="operator">);</span>
|
||
|
||
QObject<span class="operator">::</span>connect<span class="operator">(</span>btnStartStop<span class="operator">,</span> SIGNAL<span class="operator">(</span>clicked<span class="operator">()),</span><span class="keyword"> this</span><span class="operator">,</span> SLOT<span class="operator">(</span>onClickStartStop<span class="operator">()));</span>
|
||
QObject<span class="operator">::</span>connect<span class="operator">(</span>cboSerializationType<span class="operator">,</span> SIGNAL<span class="operator">(</span>currentIndexChanged<span class="operator">(</span><span class="type">int</span><span class="operator">)),</span><span class="keyword"> this</span><span class="operator">,</span> SLOT<span class="operator">(</span>onCboIndexChanged<span class="operator">(</span><span class="type">int</span><span class="operator">)));</span>
|
||
|
||
cboSerializationType<span class="operator">-></span>addItem<span class="operator">(</span><span class="string">"0- serialization_binary"</span><span class="operator">,</span> QVariant<span class="operator">((</span><span class="type">int</span><span class="operator">)</span>qx<span class="operator">::</span>service<span class="operator">::</span>QxConnect<span class="operator">::</span>serialization_binary<span class="operator">));</span>
|
||
cboSerializationType<span class="operator">-></span>addItem<span class="operator">(</span><span class="string">"1- serialization_xml"</span><span class="operator">,</span> QVariant<span class="operator">((</span><span class="type">int</span><span class="operator">)</span>qx<span class="operator">::</span>service<span class="operator">::</span>QxConnect<span class="operator">::</span>serialization_xml<span class="operator">));</span>
|
||
cboSerializationType<span class="operator">-></span>addItem<span class="operator">(</span><span class="string">"2- serialization_text"</span><span class="operator">,</span> QVariant<span class="operator">((</span><span class="type">int</span><span class="operator">)</span>qx<span class="operator">::</span>service<span class="operator">::</span>QxConnect<span class="operator">::</span>serialization_text<span class="operator">));</span>
|
||
cboSerializationType<span class="operator">-></span>addItem<span class="operator">(</span><span class="string">"3- serialization_portable_binary"</span><span class="operator">,</span> QVariant<span class="operator">((</span><span class="type">int</span><span class="operator">)</span>qx<span class="operator">::</span>service<span class="operator">::</span>QxConnect<span class="operator">::</span>serialization_portable_binary<span class="operator">));</span>
|
||
cboSerializationType<span class="operator">-></span>addItem<span class="operator">(</span><span class="string">"4- serialization_wide_binary"</span><span class="operator">,</span> QVariant<span class="operator">((</span><span class="type">int</span><span class="operator">)</span>qx<span class="operator">::</span>service<span class="operator">::</span>QxConnect<span class="operator">::</span>serialization_wide_binary<span class="operator">));</span>
|
||
cboSerializationType<span class="operator">-></span>addItem<span class="operator">(</span><span class="string">"5- serialization_wide_xml"</span><span class="operator">,</span> QVariant<span class="operator">((</span><span class="type">int</span><span class="operator">)</span>qx<span class="operator">::</span>service<span class="operator">::</span>QxConnect<span class="operator">::</span>serialization_wide_xml<span class="operator">));</span>
|
||
cboSerializationType<span class="operator">-></span>addItem<span class="operator">(</span><span class="string">"6- serialization_wide_text"</span><span class="operator">,</span> QVariant<span class="operator">((</span><span class="type">int</span><span class="operator">)</span>qx<span class="operator">::</span>service<span class="operator">::</span>QxConnect<span class="operator">::</span>serialization_wide_text<span class="operator">));</span>
|
||
cboSerializationType<span class="operator">-></span>addItem<span class="operator">(</span><span class="string">"7- serialization_polymorphic_binary"</span><span class="operator">,</span> QVariant<span class="operator">((</span><span class="type">int</span><span class="operator">)</span>qx<span class="operator">::</span>service<span class="operator">::</span>QxConnect<span class="operator">::</span>serialization_polymorphic_binary<span class="operator">));</span>
|
||
cboSerializationType<span class="operator">-></span>addItem<span class="operator">(</span><span class="string">"8- serialization_polymorphic_xml"</span><span class="operator">,</span> QVariant<span class="operator">((</span><span class="type">int</span><span class="operator">)</span>qx<span class="operator">::</span>service<span class="operator">::</span>QxConnect<span class="operator">::</span>serialization_polymorphic_xml<span class="operator">));</span>
|
||
cboSerializationType<span class="operator">-></span>addItem<span class="operator">(</span><span class="string">"9- serialization_polymorphic_text"</span><span class="operator">,</span> QVariant<span class="operator">((</span><span class="type">int</span><span class="operator">)</span>qx<span class="operator">::</span>service<span class="operator">::</span>QxConnect<span class="operator">::</span>serialization_polymorphic_text<span class="operator">));</span>
|
||
cboSerializationType<span class="operator">-></span>setCurrentIndex<span class="operator">(</span>cboSerializationType<span class="operator">-></span>findData<span class="operator">(</span>QVariant<span class="operator">((</span><span class="type">int</span><span class="operator">)</span>qx<span class="operator">::</span>service<span class="operator">::</span>QxConnect<span class="operator">::</span>getSingleton<span class="operator">()-></span>getSerializationType<span class="operator">())));</span>
|
||
|
||
spinPortNumber<span class="operator">-></span>setValue<span class="operator">(</span><span class="int">7694</span><span class="operator">);</span>
|
||
spinThreadCount<span class="operator">-></span>setValue<span class="operator">(</span>qx<span class="operator">::</span>service<span class="operator">::</span>QxConnect<span class="operator">::</span>getSingleton<span class="operator">()-></span>getThreadCount<span class="operator">());</span>
|
||
onServerIsRunning<span class="operator">(</span><span class="bool">false</span><span class="operator">,</span> NULL<span class="operator">);</span>
|
||
onClickStartStop<span class="operator">();
|
||
}</span></pre>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<br>
|
||
<i>onClickStartStop()</i> event can start and stop the server.<br>
|
||
Application server must <i>serialize</i> reply to send to clients : you can choose the serialization type
|
||
with the combobox <i>cboSerializationType</i>.<br>
|
||
For more information about all serialization types supported by QxOrm library, <a
|
||
href="../qxorm_en/manual.html#manual_60">read the manual here</a>.<br>
|
||
In most cases, binary serialization is strongly recommended for a network transaction because it is
|
||
fastest and smallest to limit traffic over network.<br>
|
||
We define also a port number for the application server with the field <i>spinPortNumber</i>.<br>
|
||
An important parameter is the <u>threads count</u> available : this is the <u>clients count that can send
|
||
a request in same time</u>.<br>
|
||
Default value for this parameter is 30, you can modify this value if you estimate more clients connected
|
||
simultaneously.<br>
|
||
If there is more clients than threads available, the request waits for a free thread, then the
|
||
transaction is normally executed.<br>
|
||
<br>
|
||
<a name="tuto_103"><u>
|
||
<font color="#100D5A">1.3- File description <i>main_dlg.cpp</i>, method <i>loadServices()</i>
|
||
</font>
|
||
</u></a>
|
||
<br><br>
|
||
<table border="1" bgcolor="#FFFFFF">
|
||
<col>
|
||
<tbody>
|
||
<tr>
|
||
<td title="main_dlg::loadServices()">
|
||
<pre><span class="type">void</span> main_dlg<span class="operator">::</span>loadServices<span class="operator">()
|
||
{</span><span class="comment">
|
||
// Required to be sure to load all services dll : create a dummy service for each dll
|
||
// It is also possible to create a 'plugin system' to load services
|
||
</span> server_infos dummy_01<span class="operator">;</span> Q_UNUSED<span class="operator">(</span>dummy_01<span class="operator">);
|
||
}</span></pre>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<br>
|
||
<i>loadServices()</i> method is the only dependency with services provided by application server.<br>
|
||
This method creates a ghost instance of a service to be sure that all services containing in dll are
|
||
loaded when server is running.<br>
|
||
For a production software, you can provide <u>a plugin mechanism</u> to load all services.<br>
|
||
<br>
|
||
<a name="tuto_104"><u>
|
||
<font color="#100D5A">1.4- File description <i>main_dlg.cpp</i>, method <i>onClickStartStop()</i>
|
||
</font>
|
||
</u></a>
|
||
<br><br>
|
||
<table border="1" bgcolor="#FFFFFF">
|
||
<col>
|
||
<tbody>
|
||
<tr>
|
||
<td title="main_dlg::onClickStartStop()">
|
||
<pre><span class="type">void</span> main_dlg<span class="operator">::</span>onClickStartStop<span class="operator">()
|
||
{</span>
|
||
QApplication<span class="operator">::</span>setOverrideCursor<span class="operator">(</span>QCursor<span class="operator">(</span>Qt<span class="operator">::</span>WaitCursor<span class="operator">));</span><span class="flow">
|
||
if</span><span class="operator"> (</span>m_pThreadPool<span class="operator">)
|
||
{</span>
|
||
m_pThreadPool<span class="operator">-></span>disconnect<span class="operator">();</span>
|
||
m_pThreadPool<span class="operator">.</span>reset<span class="operator">();</span>
|
||
txtError<span class="operator">-></span>setPlainText<span class="operator">(</span><span class="string">""</span><span class="operator">);</span>
|
||
txtTransaction<span class="operator">-></span>setPlainText<span class="operator">(</span><span class="string">""</span><span class="operator">);</span>
|
||
onServerIsRunning<span class="operator">(</span><span class="bool">false</span><span class="operator">,</span> NULL<span class="operator">);
|
||
}</span><span class="flow">
|
||
else</span><span class="operator">
|
||
{</span>
|
||
qx<span class="operator">::</span>service<span class="operator">::</span>QxConnect<span class="operator">::</span>getSingleton<span class="operator">()-></span>setPort<span class="operator">(</span>spinPortNumber<span class="operator">-></span>value<span class="operator">());</span>
|
||
qx<span class="operator">::</span>service<span class="operator">::</span>QxConnect<span class="operator">::</span>getSingleton<span class="operator">()-></span>setThreadCount<span class="operator">(</span>spinThreadCount<span class="operator">-></span>value<span class="operator">());</span>
|
||
qx<span class="operator">::</span>service<span class="operator">::</span>QxConnect<span class="operator">::</span>getSingleton<span class="operator">()-></span>setSerializationType<span class="operator">((</span>qx<span class="operator">::</span>service<span class="operator">::</span>QxConnect<span class="operator">::</span>serialization_type<span class="operator">)
|
||
(</span>cboSerializationType<span class="operator">-></span>itemData<span class="operator">(</span>cboSerializationType<span class="operator">-></span>currentIndex<span class="operator">()).</span>toInt<span class="operator">()));</span>
|
||
qx<span class="operator">::</span>service<span class="operator">::</span>QxConnect<span class="operator">::</span>getSingleton<span class="operator">()-></span>setCompressData<span class="operator">(</span>chkCompressData<span class="operator">-></span>isChecked<span class="operator">());</span>
|
||
qx<span class="operator">::</span>service<span class="operator">::</span>QxConnect<span class="operator">::</span>getSingleton<span class="operator">()-></span>setEncryptData<span class="operator">(</span>chkEncryptData<span class="operator">-></span>isChecked<span class="operator">());</span>
|
||
|
||
m_pThreadPool<span class="operator">.</span>reset<span class="operator">(</span><span class="keyword">new</span> qx<span class="operator">::</span>service<span class="operator">::</span>QxThreadPool<span class="operator">());</span>
|
||
QObject<span class="operator">::</span>connect<span class="operator">(</span>m_pThreadPool<span class="operator">.</span>get<span class="operator">(),</span> SIGNAL<span class="operator">(</span>error<span class="operator">(</span><span class="keyword">const</span> QString<span class="operator"> &,</span> qx<span class="operator">::</span>service<span class="operator">::</span>QxTransaction_ptr<span class="operator">)),</span><span class="keyword"> this</span><span class="operator">,</span>
|
||
SLOT<span class="operator">(</span>onError<span class="operator">(</span><span class="keyword">const</span> QString<span class="operator"> &,</span> qx<span class="operator">::</span>service<span class="operator">::</span>QxTransaction_ptr<span class="operator">)));</span>
|
||
QObject<span class="operator">::</span>connect<span class="operator">(</span>m_pThreadPool<span class="operator">.</span>get<span class="operator">(),</span> SIGNAL<span class="operator">(</span>serverIsRunning<span class="operator">(</span><span class="type">bool</span><span class="operator">,</span> qx<span class="operator">::</span>service<span class="operator">::</span>QxServer<span class="operator"> *)),</span><span class="keyword"> this</span><span class="operator">,</span>
|
||
SLOT<span class="operator">(</span>onServerIsRunning<span class="operator">(</span><span class="type">bool</span><span class="operator">,</span> qx<span class="operator">::</span>service<span class="operator">::</span>QxServer<span class="operator"> *)));</span>
|
||
QObject<span class="operator">::</span>connect<span class="operator">(</span>m_pThreadPool<span class="operator">.</span>get<span class="operator">(),</span> SIGNAL<span class="operator">(</span>transactionFinished<span class="operator">(</span>qx<span class="operator">::</span>service<span class="operator">::</span>QxTransaction_ptr<span class="operator">)),</span><span class="keyword"> this</span><span class="operator">,</span>
|
||
SLOT<span class="operator">(</span>onTransactionFinished<span class="operator">(</span>qx<span class="operator">::</span>service<span class="operator">::</span>QxTransaction_ptr<span class="operator">)));</span>
|
||
m_pThreadPool<span class="operator">-></span>start<span class="operator">();
|
||
}</span>
|
||
QApplication<span class="operator">::</span>restoreOverrideCursor<span class="operator">();
|
||
}</span></pre>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<br>
|
||
<i>onClickStartStop()</i> is called to start and stop the application server : an instance of
|
||
<i>qx::service::QxThreadPool_ptr</i> type is created (start server) or destroyed (stop server).<br>
|
||
If <i>m_pThreadPool</i> exists, then we want to stop the server : <i>m_pThreadPool.reset();</i>.<br>
|
||
Otherwise, server is not running so we want to start it :<br>
|
||
<i>m_pThreadPool.reset(new qx::service::QxThreadPool());</i>.<br>
|
||
<i>m_pThreadPool->start();</i>.<br>
|
||
<br>
|
||
Server settings are contained inside the singleton <i>qx::service::QxConnect::getSingleton()</i>.<br>
|
||
At the end, GUI subscribes to application server events (<b>SIGNAL-SLOT</b> mechanims from Qt library) to
|
||
retrieve all errors and to display the last transaction between client and server.<br>
|
||
<br>
|
||
<a name="tuto_105"><u>
|
||
<font color="#100D5A">1.5- File description <i>main_dlg.cpp</i>, methods <i>onError()</i> and
|
||
<i>onTransactionFinished()</i>
|
||
</font>
|
||
</u></a>
|
||
<br><br>
|
||
<table border="1" bgcolor="#FFFFFF">
|
||
<col>
|
||
<tbody>
|
||
<tr>
|
||
<td title="main_dlg::onError(), main_dlg::onTransactionFinished()">
|
||
<pre><span class="type">void</span> main_dlg<span class="operator">::</span>onError<span class="operator">(</span><span class="keyword">const</span> QString<span class="operator"> &</span> err<span class="operator">,</span> qx<span class="operator">::</span>service<span class="operator">::</span>QxTransaction_ptr transaction<span class="operator">)
|
||
{</span><span class="flow">
|
||
if</span><span class="operator"> (</span>err<span class="operator">.</span>isEmpty<span class="operator">()) {</span> txtError<span class="operator">-></span>setPlainText<span class="operator">(</span><span class="string">""</span><span class="operator">);</span><span class="flow"> return</span><span class="operator">; }</span>
|
||
QString errText<span class="operator"> =</span> QDateTime<span class="operator">::</span>currentDateTime<span class="operator">().</span>toString<span class="operator">(</span><span class="string">"dd.MM.yyyy hh:mm"</span><span class="operator">) +</span><span class="string"> " : "</span><span class="operator"> +</span> err<span class="operator">;</span><span class="flow">
|
||
if</span><span class="operator"> (</span>transaction<span class="operator">) {</span> errText<span class="operator"> +=</span> QString<span class="operator">(</span><span class="string">"\r\n\r\n"</span><span class="operator">) +</span> qx<span class="operator">::</span>serialization<span class="operator">::</span>xml<span class="operator">::</span>to_string<span class="operator">(*</span> transaction<span class="operator">); }</span>
|
||
txtError<span class="operator">-></span>setPlainText<span class="operator">(</span>errText<span class="operator">.</span>replace<span class="operator">(</span><span class="string">"\t"</span><span class="operator">,</span><span class="string"> " "</span><span class="operator">));
|
||
}</span><span class="type">
|
||
|
||
void</span> main_dlg<span class="operator">::</span>onTransactionFinished<span class="operator">(</span>qx<span class="operator">::</span>service<span class="operator">::</span>QxTransaction_ptr transaction<span class="operator">)
|
||
{</span><span class="flow">
|
||
if</span><span class="operator"> (!</span> transaction<span class="operator">) {</span> txtTransaction<span class="operator">-></span>setPlainText<span class="operator">(</span><span class="string">""</span><span class="operator">);</span><span class="flow"> return</span><span class="operator">; }</span>
|
||
QString text<span class="operator"> =</span> qx<span class="operator">::</span>serialization<span class="operator">::</span>xml<span class="operator">::</span>to_string<span class="operator">(*</span> transaction<span class="operator">);</span>
|
||
txtTransaction<span class="operator">-></span>setPlainText<span class="operator">(</span>text<span class="operator">.</span>replace<span class="operator">(</span><span class="string">"\t"</span><span class="operator">,</span><span class="string"> " "</span><span class="operator">));
|
||
}</span></pre>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<br>
|
||
All transactions between client and server are schematized by <i>qx::service::QxTransaction_ptr</i>
|
||
type.<br>
|
||
This class contains all informations needed to execute a service (unique id, date-time, request from
|
||
client, service to execute, reply from server, error message and error code, etc...).<br>
|
||
Transaction is serialized to XML (or JSON) format to display it in the field <i>txtTransaction</i>.<br>
|
||
<br>
|
||
<a name="tuto_106"><u>
|
||
<font color="#100D5A">1.6- Result with <i>qxServer</i> project</font>
|
||
</u></a>
|
||
<br><br>
|
||
<u><b>And... that's all</b></u> : <b>QxOrm</b> library provides an easy way to create application
|
||
server.<br>
|
||
Now your application server is ready to provide all services that you want to clients :<br>
|
||
<br>
|
||
<img alt="gui_qxServer" src="./resource/gui_qxServer.jpg" width="560" height="426"
|
||
style="border:0px solid #100D5A; border-color:#100D5A;">
|
||
<br>
|
||
<br><br>
|
||
<b><a name="tuto_20"><u>
|
||
<font color="#100D5A">2- Service layer : <i>qxService</i></font>
|
||
</u></a></b>
|
||
<br><br>
|
||
The service layer must be shared between client and server.<br>
|
||
When you build the project <i>qxService</i>, you create 2 dll (or <i>*.so</i> files on Linux) :
|
||
<i>qxServiceClient</i> and <i>qxServiceServer</i>.<br>
|
||
The compilation option <i>_QX_SERVICE_MODE_CLIENT</i> is used to know if we are building the client or
|
||
the server.<br>
|
||
<i>qmake</i> tool from Qt library and <i>*.pro</i> and <i>*.pri</i> files allow to create easily this
|
||
kind of architecture :<br>
|
||
* <a href="./resource/qxService.pri"><i>qxService.pri</i></a> file contains all dependencies and files to
|
||
compile.<br>
|
||
* <a href="./resource/qxServiceClient.pro"><i>qxServiceClient.pro</i></a> file is used only by client
|
||
mode : define <i>_QX_SERVICE_MODE_CLIENT</i> and dll target name.<br>
|
||
* <a href="./resource/qxServiceServer.pro"><i>qxServiceServer.pro</i></a> file is used only by server
|
||
mode : define dll target name.<br>
|
||
So client and server services share the same files.<br>
|
||
<u>You don't have to write any line of code to call a service</u> : server can deploy <i>headers</i>
|
||
files, <i>.dll</i> and <i>.lib</i> files (or <i>*.so</i> on Linux).<br>
|
||
<br>
|
||
<a name="tuto_201"><u>
|
||
<font color="#100D5A">2.1- First service : retrieve current date-time from server</font>
|
||
</u></a>
|
||
<br><br>
|
||
The first service provided by our application server is easy : <u>send the current server date-time to
|
||
all clients</u>.<br>
|
||
This service is available by the class <i>server_infos</i> : <i>server_infos.h</i> and
|
||
<i>server_infos.cpp</i> files.<br>
|
||
A same class can provide many services : <i>server_infos</i> class could for example send the server
|
||
name, the processor frequency, etc...<br>
|
||
Each service class contains input parameters (request from client) and output parameters (reply from
|
||
server).<br>
|
||
A parameter class (input or output) must inherit from <b>qx::service::IxParameter</b> class and must be
|
||
serializable.<br>
|
||
A service class must inherit from <b>qx::service::QxService<INPUT, OUTPUT></b> template and must
|
||
define a list of methods (list of services).<br>
|
||
It is recommended to write input parameter class, output parameter class and service class in the same
|
||
file.<br>
|
||
<br>
|
||
<a name="tuto_202"><u>
|
||
<font color="#100D5A">2.2- File description <i>server_infos.h</i></font>
|
||
</u></a>
|
||
<br><br>
|
||
<table border="1" bgcolor="#FFFFFF">
|
||
<col>
|
||
<tbody>
|
||
<tr>
|
||
<td title="server_infos.h">
|
||
<pre><span class="pre">#ifndef _QX_SERVICE_SERVER_INFOS_H_
|
||
#define _QX_SERVICE_SERVER_INFOS_H_
|
||
</span><span class="comment">
|
||
/* -- Service Input Parameters -- */</span><span class="keyword">
|
||
|
||
class</span> QX_SERVICE_DLL_EXPORT server_infos_input<span class="operator"> :</span><span class="keyword"> public</span> qx<span class="operator">::</span>service<span class="operator">::</span>IxParameter<span class="operator">
|
||
{ ; };</span>
|
||
|
||
QX_REGISTER_HPP_QX_SERVICE<span class="operator">(</span>server_infos_input<span class="operator">,</span> qx<span class="operator">::</span>service<span class="operator">::</span>IxParameter<span class="operator">,</span><span class="int"> 0</span><span class="operator">)</span><span class="keyword">
|
||
typedef</span> std<span class="operator">::</span>shared_ptr<span class="operator"><</span>server_infos_input<span class="operator">></span> server_infos_input_ptr<span class="operator">;</span><span class="comment">
|
||
|
||
/* -- Service Output Parameters -- */</span><span class="keyword">
|
||
|
||
class</span> QX_SERVICE_DLL_EXPORT server_infos_output<span class="operator"> :</span><span class="keyword"> public</span> qx<span class="operator">::</span>service<span class="operator">::</span>IxParameter<span class="operator">
|
||
{</span><span class="keyword"> public</span><span class="operator">:</span> QDateTime current_date_time<span class="operator">; };</span>
|
||
|
||
QX_REGISTER_HPP_QX_SERVICE<span class="operator">(</span>server_infos_output<span class="operator">,</span> qx<span class="operator">::</span>service<span class="operator">::</span>IxParameter<span class="operator">,</span><span class="int"> 0</span><span class="operator">)</span><span class="keyword">
|
||
typedef</span> std<span class="operator">::</span>shared_ptr<span class="operator"><</span>server_infos_output<span class="operator">></span> server_infos_output_ptr<span class="operator">;</span><span class="comment">
|
||
|
||
/* -- Service Definition -- */</span><span class="keyword">
|
||
|
||
typedef</span> qx<span class="operator">::</span>service<span class="operator">::</span>QxService<span class="operator"><</span>server_infos_input<span class="operator">,</span> server_infos_output<span class="operator">></span> server_infos_base_class<span class="operator">;</span><span class="keyword">
|
||
class</span> QX_SERVICE_DLL_EXPORT server_infos<span class="operator"> :</span><span class="keyword"> public</span> server_infos_base_class<span class="operator">
|
||
{</span><span class="keyword">
|
||
public</span><span class="operator">:</span>
|
||
server_infos<span class="operator">() :</span> server_infos_base_class<span class="operator">(</span><span class="string">"server_infos"</span><span class="operator">) { ; }</span><span class="keyword">
|
||
virtual</span><span class="operator"> ~</span>server_infos<span class="operator">() { ; }</span><span class="type">
|
||
void</span> get_current_date_time<span class="operator">();
|
||
};</span>
|
||
|
||
QX_REGISTER_HPP_QX_SERVICE<span class="operator">(</span>server_infos<span class="operator">,</span> qx<span class="operator">::</span>service<span class="operator">::</span>IxService<span class="operator">,</span><span class="int"> 0</span><span class="operator">)</span><span class="keyword">
|
||
typedef</span> std<span class="operator">::</span>shared_ptr<span class="operator"><</span>server_infos<span class="operator">></span> server_infos_ptr<span class="operator">;</span><span class="pre">
|
||
|
||
#endif // _QX_SERVICE_SERVER_INFOS_H_</span></pre>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<br>
|
||
<i>server_infos.h</i> file contains 3 classes :<br>
|
||
* <u><i>server_infos_input</i></u> : inherits from <i>qx::service::IxParameter</i> class (request from
|
||
client). Our test service doesn't need any input parameter, so this class is empty.<br>
|
||
* <u><i>server_infos_output</i></u> : inherits from <i>qx::service::IxParameter</i> class (reply from
|
||
server). This class contains only 1 property, the current server date-time.<br>
|
||
* <u><i>server_infos</i></u> : inherits from <i>qx::service::QxService<INPUT, OUTPUT></i> template
|
||
and contains all methods to call services : only 1 method for our service to retrieve the current server
|
||
date-time.<br>
|
||
<br>
|
||
Those 3 classes must be registered in QxOrm context, like a persitent class (see <b>qxBlog</b>
|
||
tutorial).<br>
|
||
This is why we are using the <i>QX_REGISTER_HPP_QX_SERVICE</i> macro for those 3 classes.<br>
|
||
Moreover, to manage memory and avoid memory leaks, we use smart-pointers from standard library :
|
||
<i>std::shared_ptr</i>.<br>
|
||
<b>QxService</b> module works with smart-pointers, this is why it is strongly recommended to create some
|
||
<i>typedef</i> : for example, <i>typedef std::shared_ptr<server_infos_input>
|
||
server_infos_input_ptr;</i>.<br>
|
||
Finally, constructor service must provide class name under a string format : this is necessary for the
|
||
QxOrm <i>introspection</i> engine to create services instances.<br>
|
||
<br>
|
||
<a name="tuto_203"><u>
|
||
<font color="#100D5A">2.3- File description <i>server_infos.cpp</i></font>
|
||
</u></a>
|
||
<br><br>
|
||
<table border="1" bgcolor="#FFFFFF">
|
||
<col>
|
||
<tbody>
|
||
<tr>
|
||
<td title="server_infos.cpp">
|
||
<pre><span class="pre">#include "../../include/precompiled.h"
|
||
|
||
#include "../../include/service/server_infos.h"
|
||
|
||
#include <QxOrm_Impl.h>
|
||
</span>
|
||
QX_REGISTER_CPP_QX_SERVICE<span class="operator">(</span>server_infos_input<span class="operator">)</span>
|
||
QX_REGISTER_CPP_QX_SERVICE<span class="operator">(</span>server_infos_output<span class="operator">)</span>
|
||
QX_REGISTER_CPP_QX_SERVICE<span class="operator">(</span>server_infos<span class="operator">)</span><span class="keyword">
|
||
|
||
namespace</span> qx<span class="operator"> {</span><span class="keyword">
|
||
|
||
template</span><span class="operator"> <></span><span class="type"> void</span> register_class<span class="operator">(</span>QxClass<span class="operator"><</span>server_infos_input<span class="operator">> &</span> t<span class="operator">)
|
||
{</span> Q_UNUSED<span class="operator">(</span>t<span class="operator">); }</span><span class="keyword">
|
||
|
||
template</span><span class="operator"> <></span><span class="type"> void</span> register_class<span class="operator">(</span>QxClass<span class="operator"><</span>server_infos_output<span class="operator">> &</span> t<span class="operator">)
|
||
{</span> t<span class="operator">.</span>data<span class="operator">(&</span> server_infos_output<span class="operator">::</span>current_date_time<span class="operator">,</span><span class="string"> "current_date_time"</span><span class="operator">); }</span><span class="keyword">
|
||
|
||
template</span><span class="operator"> <></span><span class="type"> void</span> register_class<span class="operator">(</span>QxClass<span class="operator"><</span>server_infos<span class="operator">> &</span> t<span class="operator">)
|
||
{</span> t<span class="operator">.</span>fct_0<span class="operator"><</span><span class="type">void</span><span class="operator">>(&</span> server_infos<span class="operator">::</span>get_current_date_time<span class="operator">,</span><span class="string"> "get_current_date_time"</span><span class="operator">); }
|
||
|
||
}</span><span class="comment"> // namespace qx
|
||
</span><span class="pre">
|
||
#ifdef _QX_SERVICE_MODE_CLIENT
|
||
</span><span class="type">
|
||
void</span> server_infos<span class="operator">::</span>get_current_date_time<span class="operator">()
|
||
{</span> qx<span class="operator">::</span>service<span class="operator">::</span>execute_client<span class="operator">(</span><span class="keyword">this</span><span class="operator">,</span><span class="string"> "get_current_date_time"</span><span class="operator">); }</span><span class="pre">
|
||
|
||
#else // _QX_SERVICE_MODE_CLIENT
|
||
</span><span class="type">
|
||
void</span> server_infos<span class="operator">::</span>get_current_date_time<span class="operator">()
|
||
{</span>
|
||
server_infos_output_ptr output<span class="operator"> =</span> server_infos_output_ptr<span class="operator">(</span><span class="keyword">new</span> server_infos_output<span class="operator">());</span>
|
||
output<span class="operator">-></span>current_date_time<span class="operator"> =</span> QDateTime<span class="operator">::</span>currentDateTime<span class="operator">();</span>
|
||
setOutputParameter<span class="operator">(</span>output<span class="operator">);</span>
|
||
setMessageReturn<span class="operator">(</span><span class="bool">true</span><span class="operator">);
|
||
}</span><span class="pre">
|
||
|
||
#endif // _QX_SERVICE_MODE_CLIENT</span></pre>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<br>
|
||
<i>server_infos.cpp</i> file contains the implementation of service for the client mode and server
|
||
mode.<br>
|
||
<i>QX_REGISTER_CPP_QX_SERVICE</i> macro registers classes into QxOrm context, like a persistent class
|
||
(see <b>qxBlog</b> tutorial).<br>
|
||
Then, we write the mapping function <i>void qx::register_class(...)</i> :<br>
|
||
* The 2 parameters classes (input and output) register all properties needed to execute a client request
|
||
(no parameter for our test service), and all properties needed to send a reply (current server date-time
|
||
: <i>t.data(& server_infos_output::current_date_time, "current_date_time");</i>).<br>
|
||
* The service class need to register all methods to call services, so in our case :
|
||
<i>t.fct_0<void>(& server_infos::get_current_date_time, "get_current_date_time");</i>.<br>
|
||
<br>
|
||
<b>Note :</b> all services methods need to have the same signature : <u>no return value, and no
|
||
argument</u> (for example : <i>void my_service()</i>).<br>
|
||
Indeed, in a service method, all input parameters are available with <i>getInputParameter()</i> function
|
||
(of <i>server_infos_input_ptr</i> type in our example).<br>
|
||
Output parameters can be set by <i>setOutputParameter()</i> function (of <i>server_infos_output_ptr</i>
|
||
type in our example).<br>
|
||
A return value of <i>qx_bool</i> type is necessary to indicate that the transaction has been executed
|
||
successfully or with an error (you can set an error code and an error description).<br>
|
||
It is very important to write <i>setMessageReturn(true);</i> to the end of each service method.<br>
|
||
<br>
|
||
The last part of our file contains the implementation of <i>server_infos::get_current_date_time()</i>
|
||
method for the client mode and server mode.<br>
|
||
In client mode, it is very easy : <i>qx::service::execute_client(this, "get_current_date_time");</i>.<br>
|
||
In server mode, we retrieve the current date time, then we set it into output parameter, then we indicate
|
||
that the transaction has been executed without error.<br>
|
||
<br>
|
||
<a name="tuto_204"><u>
|
||
<font color="#100D5A">2.4- Second service : work with a persistent class</font>
|
||
</u></a>
|
||
<br><br>
|
||
<i>qxService</i> project contains another sample more complex with a persistent class to transfer between
|
||
client and server (<i>user</i> class), and some basics actions on a database (<i>SELECT, INSERT, UPDATE,
|
||
DELETE, etc...</i>).<br>
|
||
This second sample transfer complex structures over network : pointers, smart-pointers, collections,
|
||
search criterias, etc...<br>
|
||
<br>
|
||
<table border="1" bgcolor="#FFFFFF">
|
||
<col>
|
||
<tbody>
|
||
<tr>
|
||
<td title="user_service.cpp">
|
||
<pre><span class="pre">#include "../../include/precompiled.h"
|
||
|
||
#include "../../include/service/user_service.h"
|
||
|
||
#include "../../include/dao/user_manager.h"
|
||
|
||
#include <QxOrm_Impl.h>
|
||
</span>
|
||
QX_REGISTER_CPP_QX_SERVICE<span class="operator">(</span>user_service_input<span class="operator">)</span>
|
||
QX_REGISTER_CPP_QX_SERVICE<span class="operator">(</span>user_service_output<span class="operator">)</span>
|
||
QX_REGISTER_CPP_QX_SERVICE<span class="operator">(</span>user_service<span class="operator">)</span><span class="keyword">
|
||
|
||
namespace</span> qx<span class="operator"> {</span><span class="keyword">
|
||
|
||
template</span><span class="operator"> <></span><span class="type"> void</span> register_class<span class="operator">(</span>QxClass<span class="operator"><</span>user_service_input<span class="operator">> &</span> t<span class="operator">)
|
||
{</span>
|
||
t<span class="operator">.</span>data<span class="operator">(&</span> user_service_input<span class="operator">::</span>id<span class="operator">,</span><span class="string"> "id"</span><span class="operator">);</span>
|
||
t<span class="operator">.</span>data<span class="operator">(&</span> user_service_input<span class="operator">::</span>user<span class="operator">,</span><span class="string"> "user"</span><span class="operator">);</span>
|
||
t<span class="operator">.</span>data<span class="operator">(&</span> user_service_input<span class="operator">::</span>criteria<span class="operator">,</span><span class="string"> "criteria"</span><span class="operator">);
|
||
}</span><span class="keyword">
|
||
|
||
template</span><span class="operator"> <></span><span class="type"> void</span> register_class<span class="operator">(</span>QxClass<span class="operator"><</span>user_service_output<span class="operator">> &</span> t<span class="operator">)
|
||
{</span>
|
||
t<span class="operator">.</span>data<span class="operator">(&</span> user_service_output<span class="operator">::</span>user<span class="operator">,</span><span class="string"> "user"</span><span class="operator">);</span>
|
||
t<span class="operator">.</span>data<span class="operator">(&</span> user_service_output<span class="operator">::</span>list_of_users<span class="operator">,</span><span class="string"> "list_of_users"</span><span class="operator">);
|
||
}</span><span class="keyword">
|
||
|
||
template</span><span class="operator"> <></span><span class="type"> void</span> register_class<span class="operator">(</span>QxClass<span class="operator"><</span>user_service<span class="operator">> &</span> t<span class="operator">)
|
||
{</span>
|
||
t<span class="operator">.</span>fct_0<span class="operator"><</span><span class="type">void</span><span class="operator">>(&</span> user_service<span class="operator">::</span>insert<span class="operator">,</span><span class="string"> "insert"</span><span class="operator">);</span>
|
||
t<span class="operator">.</span>fct_0<span class="operator"><</span><span class="type">void</span><span class="operator">>(&</span> user_service<span class="operator">::</span>update<span class="operator">,</span><span class="string"> "update"</span><span class="operator">);</span>
|
||
t<span class="operator">.</span>fct_0<span class="operator"><</span><span class="type">void</span><span class="operator">>(&</span> user_service<span class="operator">::</span>remove<span class="operator">,</span><span class="string"> "remove"</span><span class="operator">);</span>
|
||
t<span class="operator">.</span>fct_0<span class="operator"><</span><span class="type">void</span><span class="operator">>(&</span> user_service<span class="operator">::</span>remove_all<span class="operator">,</span><span class="string"> "remove_all"</span><span class="operator">);</span>
|
||
t<span class="operator">.</span>fct_0<span class="operator"><</span><span class="type">void</span><span class="operator">>(&</span> user_service<span class="operator">::</span>fetch_by_id<span class="operator">,</span><span class="string"> "fetch_by_id"</span><span class="operator">);</span>
|
||
t<span class="operator">.</span>fct_0<span class="operator"><</span><span class="type">void</span><span class="operator">>(&</span> user_service<span class="operator">::</span>fetch_all<span class="operator">,</span><span class="string"> "fetch_all"</span><span class="operator">);</span>
|
||
t<span class="operator">.</span>fct_0<span class="operator"><</span><span class="type">void</span><span class="operator">>(&</span> user_service<span class="operator">::</span>get_by_criteria<span class="operator">,</span><span class="string"> "get_by_criteria"</span><span class="operator">);
|
||
}
|
||
|
||
}</span><span class="comment"> // namespace qx
|
||
</span><span class="pre">
|
||
#ifdef _QX_SERVICE_MODE_CLIENT
|
||
</span><span class="type">
|
||
void</span> user_service<span class="operator">::</span>insert<span class="operator">() {</span> qx<span class="operator">::</span>service<span class="operator">::</span>execute_client<span class="operator">(</span><span class="keyword">this</span><span class="operator">,</span><span class="string"> "insert"</span><span class="operator">); }</span><span class="type">
|
||
void</span> user_service<span class="operator">::</span>update<span class="operator">() {</span> qx<span class="operator">::</span>service<span class="operator">::</span>execute_client<span class="operator">(</span><span class="keyword">this</span><span class="operator">,</span><span class="string"> "update"</span><span class="operator">); }</span><span class="type">
|
||
void</span> user_service<span class="operator">::</span>remove<span class="operator">() {</span> qx<span class="operator">::</span>service<span class="operator">::</span>execute_client<span class="operator">(</span><span class="keyword">this</span><span class="operator">,</span><span class="string"> "remove"</span><span class="operator">); }</span><span class="type">
|
||
void</span> user_service<span class="operator">::</span>remove_all<span class="operator">() {</span> qx<span class="operator">::</span>service<span class="operator">::</span>execute_client<span class="operator">(</span><span class="keyword">this</span><span class="operator">,</span><span class="string"> "remove_all"</span><span class="operator">); }</span><span class="type">
|
||
void</span> user_service<span class="operator">::</span>fetch_by_id<span class="operator">() {</span> qx<span class="operator">::</span>service<span class="operator">::</span>execute_client<span class="operator">(</span><span class="keyword">this</span><span class="operator">,</span><span class="string"> "fetch_by_id"</span><span class="operator">); }</span><span class="type">
|
||
void</span> user_service<span class="operator">::</span>fetch_all<span class="operator">() {</span> qx<span class="operator">::</span>service<span class="operator">::</span>execute_client<span class="operator">(</span><span class="keyword">this</span><span class="operator">,</span><span class="string"> "fetch_all"</span><span class="operator">); }</span><span class="type">
|
||
void</span> user_service<span class="operator">::</span>get_by_criteria<span class="operator">() {</span> qx<span class="operator">::</span>service<span class="operator">::</span>execute_client<span class="operator">(</span><span class="keyword">this</span><span class="operator">,</span><span class="string"> "get_by_criteria"</span><span class="operator">); }</span><span class="pre">
|
||
|
||
#else // _QX_SERVICE_MODE_CLIENT
|
||
</span><span class="type">
|
||
void</span> user_service<span class="operator">::</span>insert<span class="operator">()
|
||
{</span>
|
||
user_service_input_ptr input<span class="operator"> =</span> getInputParameter<span class="operator">();</span><span class="flow">
|
||
if</span><span class="operator"> (!</span> input<span class="operator">) {</span> setMessageReturn<span class="operator">(</span><span class="int">0</span><span class="operator">,</span><span class="string"> "invalid input parameter to call service 'user_service::insert()'"</span><span class="operator">);</span><span class="flow"> return</span><span class="operator">; }</span>
|
||
QSqlError err<span class="operator"> =</span> user_manager<span class="operator">().</span>insert<span class="operator">(</span>input<span class="operator">-></span>user<span class="operator">);</span><span class="flow">
|
||
if</span><span class="operator"> (</span>err<span class="operator">.</span>isValid<span class="operator">()) {</span> setMessageReturn<span class="operator">(</span><span class="int">0</span><span class="operator">,</span> err<span class="operator">.</span>text<span class="operator">());</span><span class="flow"> return</span><span class="operator">; }</span>
|
||
user_service_output_ptr output<span class="operator"> =</span> user_service_output_ptr<span class="operator">(</span><span class="keyword">new</span> user_service_output<span class="operator">());</span>
|
||
output<span class="operator">-></span>user<span class="operator"> =</span> input<span class="operator">-></span>user<span class="operator">;</span>
|
||
setOutputParameter<span class="operator">(</span>output<span class="operator">);</span>
|
||
setMessageReturn<span class="operator">(</span><span class="bool">true</span><span class="operator">);
|
||
}</span><span class="type">
|
||
|
||
void</span> user_service<span class="operator">::</span>update<span class="operator">()
|
||
{</span>
|
||
user_service_input_ptr input<span class="operator"> =</span> getInputParameter<span class="operator">();</span><span class="flow">
|
||
if</span><span class="operator"> (!</span> input<span class="operator">) {</span> setMessageReturn<span class="operator">(</span><span class="int">0</span><span class="operator">,</span><span class="string"> "invalid input parameter to call service 'user_service::update()'"</span><span class="operator">);</span><span class="flow"> return</span><span class="operator">; }</span>
|
||
QSqlError err<span class="operator"> =</span> user_manager<span class="operator">().</span>update<span class="operator">(</span>input<span class="operator">-></span>user<span class="operator">);</span><span class="flow">
|
||
if</span><span class="operator"> (</span>err<span class="operator">.</span>isValid<span class="operator">()) {</span> setMessageReturn<span class="operator">(</span><span class="int">0</span><span class="operator">,</span> err<span class="operator">.</span>text<span class="operator">()); }</span><span class="flow">
|
||
else</span><span class="operator"> {</span> setMessageReturn<span class="operator">(</span><span class="bool">true</span><span class="operator">); }
|
||
}</span><span class="type">
|
||
|
||
void</span> user_service<span class="operator">::</span>remove<span class="operator">()
|
||
{</span>
|
||
user_service_input_ptr input<span class="operator"> =</span> getInputParameter<span class="operator">();</span><span class="flow">
|
||
if</span><span class="operator"> (!</span> input<span class="operator">) {</span> setMessageReturn<span class="operator">(</span><span class="int">0</span><span class="operator">,</span><span class="string"> "invalid input parameter to call service 'user_service::remove()'"</span><span class="operator">);</span><span class="flow"> return</span><span class="operator">; }</span>
|
||
user_ptr user_tmp<span class="operator"> =</span> user_ptr<span class="operator">(</span><span class="keyword">new</span> user<span class="operator">());</span>
|
||
user_tmp<span class="operator">-></span>id<span class="operator"> =</span> input<span class="operator">-></span>id<span class="operator">;</span>
|
||
QSqlError err<span class="operator"> =</span> user_manager<span class="operator">().</span>remove<span class="operator">(</span>user_tmp<span class="operator">);</span><span class="flow">
|
||
if</span><span class="operator"> (</span>err<span class="operator">.</span>isValid<span class="operator">()) {</span> setMessageReturn<span class="operator">(</span><span class="int">0</span><span class="operator">,</span> err<span class="operator">.</span>text<span class="operator">()); }</span><span class="flow">
|
||
else</span><span class="operator"> {</span> setMessageReturn<span class="operator">(</span><span class="bool">true</span><span class="operator">); }
|
||
}</span><span class="type">
|
||
|
||
void</span> user_service<span class="operator">::</span>remove_all<span class="operator">()
|
||
{</span>
|
||
QSqlError err<span class="operator"> =</span> user_manager<span class="operator">().</span>remove_all<span class="operator">();</span><span class="flow">
|
||
if</span><span class="operator"> (</span>err<span class="operator">.</span>isValid<span class="operator">()) {</span> setMessageReturn<span class="operator">(</span><span class="int">0</span><span class="operator">,</span> err<span class="operator">.</span>text<span class="operator">()); }</span><span class="flow">
|
||
else</span><span class="operator"> {</span> setMessageReturn<span class="operator">(</span><span class="bool">true</span><span class="operator">); }
|
||
}</span><span class="type">
|
||
|
||
void</span> user_service<span class="operator">::</span>fetch_by_id<span class="operator">()
|
||
{</span>
|
||
user_service_input_ptr input<span class="operator"> =</span> getInputParameter<span class="operator">();</span><span class="flow">
|
||
if</span><span class="operator"> (!</span> input<span class="operator">) {</span> setMessageReturn<span class="operator">(</span><span class="int">0</span><span class="operator">,</span><span class="string"> "invalid input parameter to call service 'user_service::fetch_by_id()'"</span><span class="operator">);</span><span class="flow"> return</span><span class="operator">; }</span>
|
||
user_ptr user_output<span class="operator"> =</span> user_ptr<span class="operator">(</span><span class="keyword">new</span> user<span class="operator">());</span>
|
||
user_output<span class="operator">-></span>id<span class="operator"> =</span> input<span class="operator">-></span>id<span class="operator">;</span>
|
||
QSqlError err<span class="operator"> =</span> user_manager<span class="operator">().</span>fetch_by_id<span class="operator">(</span>user_output<span class="operator">);</span><span class="flow">
|
||
if</span><span class="operator"> (</span>err<span class="operator">.</span>isValid<span class="operator">()) {</span> setMessageReturn<span class="operator">(</span><span class="int">0</span><span class="operator">,</span> err<span class="operator">.</span>text<span class="operator">());</span><span class="flow"> return</span><span class="operator">; }</span>
|
||
user_service_output_ptr output<span class="operator"> =</span> user_service_output_ptr<span class="operator">(</span><span class="keyword">new</span> user_service_output<span class="operator">());</span>
|
||
output<span class="operator">-></span>user<span class="operator"> =</span> user_output<span class="operator">;</span>
|
||
setOutputParameter<span class="operator">(</span>output<span class="operator">);</span>
|
||
setMessageReturn<span class="operator">(</span><span class="bool">true</span><span class="operator">);
|
||
}</span><span class="type">
|
||
|
||
void</span> user_service<span class="operator">::</span>fetch_all<span class="operator">()
|
||
{</span>
|
||
list_of_users_ptr list_of_users_output<span class="operator"> =</span> list_of_users_ptr<span class="operator">(</span><span class="keyword">new</span> list_of_users<span class="operator">());</span>
|
||
QSqlError err<span class="operator"> =</span> user_manager<span class="operator">().</span>fetch_all<span class="operator">(</span>list_of_users_output<span class="operator">);</span><span class="flow">
|
||
if</span><span class="operator"> (</span>err<span class="operator">.</span>isValid<span class="operator">()) {</span> setMessageReturn<span class="operator">(</span><span class="int">0</span><span class="operator">,</span> err<span class="operator">.</span>text<span class="operator">());</span><span class="flow"> return</span><span class="operator">; }</span>
|
||
user_service_output_ptr output<span class="operator"> =</span> user_service_output_ptr<span class="operator">(</span><span class="keyword">new</span> user_service_output<span class="operator">());</span>
|
||
output<span class="operator">-></span>list_of_users<span class="operator"> =</span> list_of_users_output<span class="operator">;</span>
|
||
setOutputParameter<span class="operator">(</span>output<span class="operator">);</span>
|
||
setMessageReturn<span class="operator">(</span><span class="bool">true</span><span class="operator">);
|
||
}</span><span class="type">
|
||
|
||
void</span> user_service<span class="operator">::</span>get_by_criteria<span class="operator">()
|
||
{</span>
|
||
user_service_input_ptr input<span class="operator"> =</span> getInputParameter<span class="operator">();</span><span class="flow">
|
||
if</span><span class="operator"> (!</span> input<span class="operator">) {</span> setMessageReturn<span class="operator">(</span><span class="int">0</span><span class="operator">,</span><span class="string"> "invalid input parameter to call service 'user_service::get_by_criteria()'"</span><span class="operator">);</span><span class="flow"> return</span><span class="operator">; }</span>
|
||
list_of_users_ptr list_of_users_output<span class="operator"> =</span> list_of_users_ptr<span class="operator">(</span><span class="keyword">new</span> list_of_users<span class="operator">());</span>
|
||
QSqlError err<span class="operator"> =</span> user_manager<span class="operator">().</span>get_by_criteria<span class="operator">(</span>input<span class="operator">-></span>criteria<span class="operator">,</span> list_of_users_output<span class="operator">);</span><span class="flow">
|
||
if</span><span class="operator"> (</span>err<span class="operator">.</span>isValid<span class="operator">()) {</span> setMessageReturn<span class="operator">(</span><span class="int">0</span><span class="operator">,</span> err<span class="operator">.</span>text<span class="operator">());</span><span class="flow"> return</span><span class="operator">; }</span>
|
||
user_service_output_ptr output<span class="operator"> =</span> user_service_output_ptr<span class="operator">(</span><span class="keyword">new</span> user_service_output<span class="operator">());</span>
|
||
output<span class="operator">-></span>list_of_users<span class="operator"> =</span> list_of_users_output<span class="operator">;</span>
|
||
setOutputParameter<span class="operator">(</span>output<span class="operator">);</span>
|
||
setMessageReturn<span class="operator">(</span><span class="bool">true</span><span class="operator">);
|
||
}</span><span class="pre">
|
||
|
||
#endif // _QX_SERVICE_MODE_CLIENT
|
||
</span></pre>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<br>
|
||
Now, our application server is finished and provides multiple services.<br>
|
||
It's time to write a client to call our services...<br>
|
||
<br><br>
|
||
<b><a name="tuto_30"><u>
|
||
<font color="#100D5A">3- Client GUI : <i>qxClient</i></font>
|
||
</u></a></b>
|
||
<br><br>
|
||
Like <i>qxServer</i> project, <i>qxClient</i> project has a GUI designed with <b>Qt Designer</b> tool of
|
||
Qt library.<br>
|
||
There is many buttons to call all services provided by our application server.<br>
|
||
There is also a field to set an <i>ip address</i> and a <i>port number</i> to connect to our application
|
||
server.<br>
|
||
<br>
|
||
<img alt="gui_qxClient" src="./resource/gui_qxClient_01.jpg" width="549" height="405"
|
||
style="border:0px solid #100D5A; border-color:#100D5A;">
|
||
<br><br>
|
||
<a name="tuto_301"><u>
|
||
<font color="#100D5A">3.1- Method description <i>onClickBtnDateTime()</i></font>
|
||
</u></a>
|
||
<br><br>
|
||
How to retrieve the current server date-time ?<br>
|
||
Here is the code executed when a user is clicking on <i>Get Server DateTime</i> button :<br>
|
||
<br>
|
||
<table border="1" bgcolor="#FFFFFF">
|
||
<col>
|
||
<tbody>
|
||
<tr>
|
||
<td title="main_dlg::onClickBtnDateTime()">
|
||
<pre><span class="type">void</span> main_dlg<span class="operator">::</span>onClickBtnDateTime<span class="operator">()
|
||
{</span>
|
||
QApplication<span class="operator">::</span>setOverrideCursor<span class="operator">(</span>QCursor<span class="operator">(</span>Qt<span class="operator">::</span>WaitCursor<span class="operator">));</span><span class="comment">
|
||
// Create service and call method to retrieve current server date-time
|
||
</span> server_infos service<span class="operator">;</span>
|
||
service<span class="operator">.</span>get_current_date_time<span class="operator">();</span><span class="comment">
|
||
// Update transaction log
|
||
</span> updateLastTransactionLog<span class="operator">(</span>service<span class="operator">.</span>getTransaction<span class="operator">());</span>
|
||
QApplication<span class="operator">::</span>restoreOverrideCursor<span class="operator">();
|
||
}</span></pre>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<br>
|
||
<u>As you can see, the client doesn't have to write any specific code to call a service, this is just a
|
||
call to a classic method</u>.<br>
|
||
You just have to instanciate a service, then call the service method :
|
||
<i>get_current_date_time()</i>.<br>
|
||
<i>updateLastTransactionLog()</i> function log into the field the last transaction executed between
|
||
client and server (XML or JSON format).<br>
|
||
If an error occured, then a message box is displayed with an error description.<br>
|
||
To know if a service has been executed without error, you have to use the function :
|
||
<i>service.getMessageReturn();</i> (of <i>qx_bool</i> type that can contain an error code and an error
|
||
description).<br>
|
||
Finally, to retrieve the reply from server (so the current date-time), you have to use the function :
|
||
<i>service.getOutputParameter();</i> (of <i>user_service_output_ptr</i> type).<br>
|
||
<br>
|
||
<a name="tuto_302"><u>
|
||
<font color="#100D5A">3.2- Method description <i>onClickBtnDateTimeAsync()</i></font>
|
||
</u></a>
|
||
<br><br>
|
||
<table border="1" bgcolor="#FFFFFF">
|
||
<col>
|
||
<tbody>
|
||
<tr>
|
||
<td title="main_dlg::onClickBtnDateTimeAsync(), main_dlg::onDateTimeAsyncFinished()">
|
||
<pre><span class="type">void</span> main_dlg<span class="operator">::</span>onClickBtnDateTimeAsync<span class="operator">()
|
||
{</span><span class="flow">
|
||
if</span><span class="operator"> (</span>m_pDateTimeAsync<span class="operator">) {</span> qDebug<span class="operator">(</span><span class="string">"[QxOrm] '%s' transaction is already running"</span><span class="operator">,</span><span class="string"> "server_infos::get_current_date_time"</span><span class="operator">);</span><span class="flow"> return</span><span class="operator">; }</span><span class="comment">
|
||
// Create service and call method to retrieve current server date-time (async mode)
|
||
</span> server_infos_ptr service<span class="operator"> =</span> server_infos_ptr<span class="operator">(</span><span class="keyword">new</span> server_infos<span class="operator">());</span>
|
||
m_pDateTimeAsync<span class="operator">.</span>reset<span class="operator">(</span><span class="keyword">new</span> qx<span class="operator">::</span>service<span class="operator">::</span>QxClientAsync<span class="operator">());</span>
|
||
QObject<span class="operator">::</span>connect<span class="operator">(</span>m_pDateTimeAsync<span class="operator">.</span>get<span class="operator">(),</span> SIGNAL<span class="operator">(</span>finished<span class="operator">()),</span><span class="keyword"> this</span><span class="operator">,</span> SLOT<span class="operator">(</span>onDateTimeAsyncFinished<span class="operator">()));</span>
|
||
m_pDateTimeAsync<span class="operator">-></span>setService<span class="operator">(</span>service<span class="operator">,</span><span class="string"> "get_current_date_time"</span><span class="operator">);</span>
|
||
m_pDateTimeAsync<span class="operator">-></span>start<span class="operator">();
|
||
}</span><span class="type">
|
||
|
||
void</span> main_dlg<span class="operator">::</span>onDateTimeAsyncFinished<span class="operator">()
|
||
{</span><span class="flow">
|
||
if</span><span class="operator"> (!</span> m_pDateTimeAsync<span class="operator"> || !</span> m_pDateTimeAsync<span class="operator">-></span>getService<span class="operator">()) {</span><span class="flow"> return</span><span class="operator">; }</span>
|
||
updateLastTransactionLog<span class="operator">(</span>m_pDateTimeAsync<span class="operator">-></span>getService<span class="operator">()-></span>getTransaction<span class="operator">());</span>
|
||
m_pDateTimeAsync<span class="operator">.</span>reset<span class="operator">();
|
||
}</span></pre>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<br>
|
||
The second example is the code executed when a user is clicking on <i>Get Server DateTime Async</i>
|
||
button.<br>
|
||
It shows how to call a service in <u>async mode</u>, so <u>without blocking GUI</u> (waiting for a reply
|
||
from server).<br>
|
||
<b>QxOrm</b> library provides <i>qx::service::QxClientAsync</i> class to make easier async service
|
||
call.<br>
|
||
<br>
|
||
Aync call with <b>QxService</b> module is very easy :<br>
|
||
* create an instance of a service<br>
|
||
* create an instance of <i>qx::service::QxClientAsync</i> type<br>
|
||
* connect to the <i>finished</i> event (to indicate that a reply from server is available)<br>
|
||
* set the service and method to call (string format) to <i>qx::service::QxClientAsync</i> object<br>
|
||
* run the transaction with the method <i>start()</i><br>
|
||
<br>
|
||
<a name="tuto_303"><u>
|
||
<font color="#100D5A">3.3- Method description <i>onClickBtnAddUser()</i></font>
|
||
</u></a>
|
||
<br><br>
|
||
<table border="1" bgcolor="#FFFFFF">
|
||
<col>
|
||
<tbody>
|
||
<tr>
|
||
<td title="main_dlg::onClickBtnAddUser()">
|
||
<pre><span class="type">void</span> main_dlg<span class="operator">::</span>onClickBtnAddUser<span class="operator">()
|
||
{</span>
|
||
QApplication<span class="operator">::</span>setOverrideCursor<span class="operator">(</span>QCursor<span class="operator">(</span>Qt<span class="operator">::</span>WaitCursor<span class="operator">));</span><span class="comment">
|
||
// Create input parameters with user to add
|
||
</span> user_service_input_ptr input<span class="operator"> =</span> user_service_input_ptr<span class="operator">(</span><span class="keyword">new</span> user_service_input<span class="operator">());</span>
|
||
input<span class="operator">-></span>user<span class="operator"> =</span> fileUser<span class="operator">();</span><span class="comment">
|
||
// Create service to call and set input parameters
|
||
</span> user_service service<span class="operator">;</span>
|
||
service<span class="operator">.</span>setInputParameter<span class="operator">(</span>input<span class="operator">);</span>
|
||
service<span class="operator">.</span>insert<span class="operator">();</span><span class="comment">
|
||
// If transaction is ok => display user with new id added to database
|
||
</span> user_ptr output<span class="operator"> = (</span>service<span class="operator">.</span>isValidWithOutput<span class="operator">() ?</span> service<span class="operator">.</span>getOutputParameter<span class="operator">()-></span>user<span class="operator"> :</span> user_ptr<span class="operator">());</span><span class="flow">
|
||
if</span><span class="operator"> (</span>output<span class="operator">) {</span> fillUser<span class="operator">(</span>output<span class="operator">); }</span><span class="comment">
|
||
// Update transaction log
|
||
</span> updateLastTransactionLog<span class="operator">(</span>service<span class="operator">.</span>getTransaction<span class="operator">());</span>
|
||
QApplication<span class="operator">::</span>restoreOverrideCursor<span class="operator">();
|
||
}</span></pre>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<br>
|
||
The third example is the code executed when then button <i>Add</i> into <i>User transaction</i> section
|
||
is pressed.<br>
|
||
It adds a new person (<i>user</i> class) into a database.<br>
|
||
This sample shows how to pass a structure (<i>user</i> class) into input parameter of a service.<br>
|
||
<i>fileUser()</i> method creates an instance of <i>user</i> type and set properties from GUI fields.<br>
|
||
This instance is used for our service's input parameter.<br>
|
||
If transaction is executed without error, then output parameter (reply from server) contains another
|
||
instance of <i>user</i> type with the new id added into database.<br>
|
||
Finally, we write <i>fillUser()</i> method to update GUI and to display the new user id added into
|
||
database.<br>
|
||
<br>
|
||
<a name="tuto_304"><u>
|
||
<font color="#100D5A">3.4- Method description <i>onClickBtnGetAllUsers()</i></font>
|
||
</u></a>
|
||
<br><br>
|
||
<table border="1" bgcolor="#FFFFFF">
|
||
<col>
|
||
<tbody>
|
||
<tr>
|
||
<td title="main_dlg::onClickBtnGetAllUsers()">
|
||
<pre><span class="type">void</span> main_dlg<span class="operator">::</span>onClickBtnGetAllUsers<span class="operator">()
|
||
{</span>
|
||
QApplication<span class="operator">::</span>setOverrideCursor<span class="operator">(</span>QCursor<span class="operator">(</span>Qt<span class="operator">::</span>WaitCursor<span class="operator">));</span><span class="comment">
|
||
// Create service to call
|
||
</span> user_service service<span class="operator">;</span>
|
||
service<span class="operator">.</span>fetch_all<span class="operator">();</span><span class="comment">
|
||
// If transaction is ok => display in a message box the number of users fetched from database
|
||
</span> list_of_users_ptr output<span class="operator"> = (</span>service<span class="operator">.</span>isValidWithOutput<span class="operator">() ?</span> service<span class="operator">.</span>getOutputParameter<span class="operator">()-></span>list_of_users<span class="operator"> :</span> list_of_users_ptr<span class="operator">());</span><span class="flow">
|
||
if</span><span class="operator"> (</span>output<span class="operator">) {</span> QMessageBox<span class="operator">::</span>information<span class="operator">(</span><span class="keyword">this</span><span class="operator">,</span><span class="string"> "qxClient - get all users"</span><span class="operator">,</span><span class="string"> "database contains '"</span><span class="operator"> +</span> QString<span class="operator">::</span>number<span class="operator">(</span>output<span class="operator">-></span>size<span class="operator">()) +</span><span class="string"> "' user(s)."</span><span class="operator">); }</span><span class="comment">
|
||
// Update transaction log
|
||
</span> updateLastTransactionLog<span class="operator">(</span>service<span class="operator">.</span>getTransaction<span class="operator">());</span>
|
||
QApplication<span class="operator">::</span>restoreOverrideCursor<span class="operator">();
|
||
}</span></pre>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<br>
|
||
The fourth example is the code executed when the button <i>Get All</i> of <i>User transaction</i> section
|
||
is pressed.<br>
|
||
It retrieves in a collection all <i>user</i> stored into database.<br>
|
||
Output parameter is a list of users : <i>stl, boost, Qt ou qx::QxCollection</i>.<br>
|
||
So, <b>QxService</b> module can share complex data structure between client and server.<br>
|
||
<br>
|
||
Now, enjoy with <b>QxOrm QxService module</b>... ;o)
|
||
<br>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<br>
|
||
<hr style="width: 80%" align="center" size="1" color="#100D5A">
|
||
<table border="0" style="width: 80%" align="center">
|
||
<col>
|
||
<col>
|
||
<col>
|
||
<tbody>
|
||
<tr>
|
||
<td align="left" valign="middle">
|
||
<img alt="QxOrm" src="./resource/logo_qxorm_small.png" width="168" height="40">
|
||
</td>
|
||
<td align="center" valign="middle">
|
||
<font size="2"><EFBFBD> 2011-202XDL Teamty - <a href="mailto:ic-east.com">ic-east.com</a></font>
|
||
</td>
|
||
<td align="right" valign="middle">
|
||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
||
<input type="hidden" name="cmd" value="_s-xclick">
|
||
<input type="hidden" name="hosted_button_id" value="2K4Z58ZYAYJ6S">
|
||
<input type="image" src="./resource/paypal_support_qxorm_library.gif" border="0" name="submit"
|
||
alt="Support QxOrm library - PayPal">
|
||
<img alt="" border="0" src="https://www.paypalobjects.com/fr_FR/i/scr/pixel.gif" width="1" height="1">
|
||
</form>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</body>
|
||
|
||
</html> |