summaryrefslogtreecommitdiff
path: root/client-qt/udm-client-qt/client_session.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'client-qt/udm-client-qt/client_session.cpp')
-rw-r--r--client-qt/udm-client-qt/client_session.cpp102
1 files changed, 99 insertions, 3 deletions
diff --git a/client-qt/udm-client-qt/client_session.cpp b/client-qt/udm-client-qt/client_session.cpp
index 56eb88d..60f462c 100644
--- a/client-qt/udm-client-qt/client_session.cpp
+++ b/client-qt/udm-client-qt/client_session.cpp
@@ -23,6 +23,31 @@
#include <boost/bind.hpp>
#include <boost/log/trivial.hpp>
+std::shared_ptr<char*> pack_data(const std::string &buf, int *size_)
+{
+ BOOST_LOG_TRIVIAL(debug)<<__FILE__<<":"<<__LINE__<<"\t"<<__func__;
+ std::shared_ptr<char*> ptr = std::make_shared<char*>(new char[buf.length() + 4]);
+ int32_t size = buf.length();
+ *size_ = size + 4;
+ (*ptr)[3] = size & 0xff;
+ (*ptr)[2] = (size>>8) & 0xff;
+ (*ptr)[1] = (size>>16) & 0xff;
+ (*ptr)[0] = (size>>24) & 0xff;
+ char *fck = (*ptr)+4;
+ memcpy(fck, buf.data(), buf.length());
+ return ptr;
+}
+
+std::shared_ptr<char*> pack_msg(client_msg *msg, int *size_)
+{
+ BOOST_LOG_TRIVIAL(debug)<<__FILE__<<":"<<__LINE__<<"\t"<<__func__;
+ BOOST_LOG_TRIVIAL(trace)<<"packing message:\n"<<msg->DebugString();
+ std::string msg_buf;
+ msg->SerializeToString(&msg_buf);
+ return pack_data(msg_buf, size_);
+}
+
+
client_session::client_session(QObject *parent, boost::asio::io_service *io_service) : QObject(parent), io_service_(*io_service), socket_(*io_service)
{
@@ -41,21 +66,92 @@ void client_session::client_connect(QString host, int port)
boost::asio::ip::tcp::endpoint ep;
ep.port(port);
ep.address(boost::asio::ip::address::from_string(host.toStdString()));
- socket_.async_connect(ep, boost::bind(&client_session::connect_handler, this, boost::asio::placeholders::error));
+ socket_.async_connect(ep, boost::bind(&client_session::handle_connect, this, boost::asio::placeholders::error));
}
-void client_session::connect_handler(const boost::system::error_code &e)
+void client_session::handle_connect(const boost::system::error_code &e)
{
BOOST_LOG_TRIVIAL(debug)<<__FILE__<<":"<<__LINE__<<"\t"<<typeid(this).name()<<"::"<<__func__;
if(e)
{
//TODO: settings for reconnect count and timeout
+ emit client_connected(false, QString::fromStdString(e.message()));
BOOST_LOG_TRIVIAL(error)<<__FILE__<<":"<<__LINE__<<"\t"<<typeid(this).name()<<"::"<<__func__<<"\terror: "<<e.message();
}
else
{
- //TODO: succesfule connection event
+ emit client_connected(true, QString::fromStdString(e.message()));
+ //listen for messages from server
+ recv_data_ = new char[4];
+ boost::asio::async_read(socket_, boost::asio::buffer(recv_data_, 4), boost::bind(&client_session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+ }
+}
+
+void client_session::handle_read(const boost::system::error_code& error, size_t bytes_transferred)
+{
+ if (!error)
+ {
+ std::string s;
+// bool parsed = false;
+ unsigned size = ntohl(*(int32_t*)recv_data_);
+ delete [] recv_data_;
+ char *buf = new char[size];
+ boost::system::error_code ec;
+ socket_.read_some(boost::asio::buffer(buf, size), ec);
+ if(ec)
+ {
+
+ }
+ //TODO: check for error
+ s.append(buf, size);
+ delete [] buf;
+ if(size != s.length())
+ {
+ delete this;
+ return;
+ }
+ //TODO:
+ server_msg msg;
+ if(msg.ParseFromString(s))
+ {
+ //parsed = true;
+ emit server_message_received(msg); //at least one more copy ...., i hope messages will be always small
+ //another way:
+ //make signal work with pointer to server_msg
+ //allocate msg via new server_msg and pass pointer to signal
+ //check if someone connected to signal and delete message if noone
+ //this will be limited to only one client connection because client will need to delete message manually
+ recv_data_ = new char[4];
+ boost::asio::async_read(socket_, boost::asio::buffer(recv_data_, 4), boost::bind(&client_session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+ }
+// if(!parsed)
+ else
+ {
+ BOOST_LOG_TRIVIAL(error)<<"failed to parse client message";
+ delete this; //close connection
+ return;
+ }
}
+ else
+ {
+ delete this;
+ }
+}
+
+void client_session::send_message(client_msg &msg)
+{
+ int size = 0;
+ std::shared_ptr<char*> ptr = pack_msg(&msg, &size);
+ boost::asio::async_write(socket_, boost::asio::buffer(*ptr, size), boost::bind(&client_session::handle_write, this, boost::asio::placeholders::error));
+}
+
+void client_session::handle_write(const boost::system::error_code& error)
+{
+ if(error)
+ {
+ //TODO: handle error
+ }
+
}
void client_session::run_io_service()