Skip to content

Commit

Permalink
Added socket communication
Browse files Browse the repository at this point in the history
  • Loading branch information
zivlakmilos committed Mar 3, 2017
1 parent 7c80f7c commit ad15c00
Show file tree
Hide file tree
Showing 7 changed files with 252 additions and 25 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ include_directories(

set(SOURCES
src/robotichand.cpp
src/socket.cpp
src/socketserver.cpp
src/server.cpp
)

Expand Down
15 changes: 9 additions & 6 deletions include/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@
#include <set>
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include "json.hpp"

#include "robotichand.h"
#include "socketserver.h"

class Server
{
public:
Server(void);
~Server(void);

const int PORT = 8272;
const int WSPORT = 8272;
const int PORT = 8273;

void start(void);
void toggleLock(void);
Expand All @@ -25,17 +28,17 @@ class Server
std::owner_less<websocketpp::connection_hdl>> WSClientList;

void onClientConnected(const websocketpp::connection_hdl &hdl);
void onClientConnected( Socket *client);
void onClientDisconnected(const websocketpp::connection_hdl &hdl);
void onMessageRecived(const websocketpp::connection_hdl &hdl,
const WSServer::message_ptr &msg);
void onMessageReceived(const std::string &message);
void onRoboticHandStateChanged(const RoboticHand::State &state);
void setupHandlers(void);

void sendState(const websocketpp::connection_hdl &client,
const RoboticHand::State &state);
nlohmann::json stateToJSON(const RoboticHand::State &state) const;

WSServer m_server;
WSServer m_WSServer;
WSClientList m_clients;
SocketServer m_socketServer;

RoboticHand m_roboticHand;
};
Expand Down
31 changes: 31 additions & 0 deletions include/socket.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef _SOCKET_H_
#define _SOCKET_H_

#include <string>
#include <thread>

class SocketServer;

class Socket
{
public:
explicit Socket(int id, SocketServer *server);
virtual ~Socket(void);

static const int BUFFER_SIZE = 1024;

void disconnect(void);
void sendString(const std::string &message);

inline int getId(void) const { return m_socket; };

private:
void receiving(void);

SocketServer *m_server;
int m_socket;

std::thread m_receivingThread;
};

#endif // _SOCKET_H_
39 changes: 39 additions & 0 deletions include/socketserver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#ifndef _SOCKET_SERVER_H_
#define _SOCKET_SERVER_H_

#include <thread>
#include <functional>
#include <list>
#include <string>

#include "socket.h"

class SocketServer
{
public:
explicit SocketServer(void);
virtual ~SocketServer(void);

void start(int port);
void messageReceived(Socket *socket, const std::string &message);
void sendToAll(const std::string &message);

inline void setOnMessageHandler(std::function<void(Socket *socket, const std::string message)> handler)
{ m_onMessageHandler = handler; };
inline void setOnClientConnectHandler(std::function<void(Socket *socket)> handler)
{ m_onClientConnectHandler = handler; };

private:
void run(void);

std::function<void(Socket *socket, const std::string &message)> m_onMessageHandler;
std::function<void(Socket *socket)> m_onClientConnectHandler;

int m_port;
int m_socket;
std::list<std::shared_ptr<Socket>> m_clients;

std::thread m_connectionThread;
};

#endif // _SOCKET_SERVER_H_
54 changes: 35 additions & 19 deletions src/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

#include <iostream>
#include <boost/bind.hpp>
#include "json.hpp"

#include "exception.h"

Expand All @@ -21,12 +20,13 @@ void Server::start(void)
try {
setupHandlers();

m_server.init_asio();
m_server.listen(Server::PORT);
m_server.start_accept();
m_WSServer.init_asio();
m_WSServer.listen(Server::WSPORT);
m_WSServer.start_accept();

m_roboticHand.open("/dev/ttyUSB1", "/dev/ttyUSB0");
m_roboticHand.lock();
m_roboticHand.open("/dev/ttyUSB0", "/dev/ttyUSB1");
//m_roboticHand.lock();
m_roboticHand.unlock();
m_roboticHand.setMode(RoboticHand::ModeAutomatic);
m_roboticHand.moveUp();
m_roboticHand.moveLeft();
Expand All @@ -35,7 +35,8 @@ void Server::start(void)
m_roboticHand.updateState();

m_roboticHand.start();
m_server.run();
m_socketServer.start(Server::PORT);
m_WSServer.run();
} catch(websocketpp::exception &ex) {
throw Exception(ex.what());
}
Expand All @@ -53,19 +54,25 @@ void Server::toggleLock(void)
void Server::onClientConnected(const websocketpp::connection_hdl &hdl)
{
m_clients.insert(hdl);
sendState(hdl, m_roboticHand.getState());
json state = stateToJSON(m_roboticHand.getState());
m_WSServer.send(hdl, state.dump(), websocketpp::frame::opcode::text);
}

void Server::onClientConnected(Socket *client)
{
json state = stateToJSON(m_roboticHand.getState());
client->sendString(state.dump());
}

void Server::onClientDisconnected(const websocketpp::connection_hdl &hdl)
{
m_clients.erase(hdl);
}

void Server::onMessageRecived(const websocketpp::connection_hdl &hdl,
const WSServer::message_ptr &msg)
void Server::onMessageReceived(const std::string &message)
{
try {
std::string command = msg->get_payload();
std::string command = message;
if(command == "mode_automatic")
m_roboticHand.setMode(RoboticHand::ModeAutomatic);
else if(command == "mode_manual")
Expand Down Expand Up @@ -150,33 +157,42 @@ void Server::onMessageRecived(const websocketpp::connection_hdl &hdl,

void Server::onRoboticHandStateChanged(const RoboticHand::State &state)
{
json data = stateToJSON(state);
m_socketServer.sendToAll(data.dump());
for(auto client : m_clients)
sendState(client, state);
m_WSServer.send(client, data.dump(), websocketpp::frame::opcode::text);
}

void Server::setupHandlers(void)
{
m_server.set_open_handler([this](const websocketpp::connection_hdl &hdl)
m_WSServer.set_open_handler([this](const websocketpp::connection_hdl &hdl)
{
onClientConnected(hdl);
});
m_server.set_close_handler([this](const websocketpp::connection_hdl &hdl)
m_socketServer.setOnClientConnectHandler([this](Socket *client)
{
onClientConnected(client);
});
m_WSServer.set_close_handler([this](const websocketpp::connection_hdl &hdl)
{
onClientDisconnected(hdl);
});
m_server.set_message_handler([this](const websocketpp::connection_hdl &hdl,
m_WSServer.set_message_handler([this](const websocketpp::connection_hdl &hdl,
const WSServer::message_ptr &msg)
{
onMessageRecived(hdl, msg);
onMessageReceived(msg->get_payload());
});
m_socketServer.setOnMessageHandler([this](const Socket *socket, const std::string &message)
{
onMessageReceived(message);
});
m_roboticHand.setOnStateChangedHandler([this](const RoboticHand::State &state)
{
onRoboticHandStateChanged(state);
});
}

void Server::sendState(const websocketpp::connection_hdl &client,
const RoboticHand::State &state)
json Server::stateToJSON(const RoboticHand::State &state) const
{
json data = {
{ "construction_down", state.constructionDown },
Expand All @@ -203,5 +219,5 @@ void Server::sendState(const websocketpp::connection_hdl &client,
break;
}

m_server.send(client, data.dump(), websocketpp::frame::opcode::text);
return data;
}
51 changes: 51 additions & 0 deletions src/socket.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include "socket.h"

#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <unistd.h>

#include "exception.h"
#include "socketserver.h"

Socket::Socket(int id, SocketServer *server)
: m_server(server),
m_socket(id)
{
m_receivingThread = std::thread([this]() {
receiving();
});
}

Socket::~Socket(void)
{
disconnect();
}

void Socket::disconnect(void)
{
close(m_socket);
}

void Socket::sendString(const std::string &message)
{
if(message.size() > BUFFER_SIZE)
throw Exception("Meesage too big");

if(send(m_socket, message.c_str(), BUFFER_SIZE, 0) < 0)
throw Exception("Can't send message");
}

void Socket::receiving(void)
{
while(true)
{
char buffer[BUFFER_SIZE];
if(recv(m_socket, buffer, BUFFER_SIZE, 0) < 0)
break;

m_server->messageReceived(this, std::string(buffer));
}
}
85 changes: 85 additions & 0 deletions src/socketserver.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#include "socketserver.h"

#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <unistd.h>

#include "exception.h"

SocketServer::SocketServer(void)
: m_onMessageHandler(nullptr),
m_onClientConnectHandler(nullptr),
m_port(0),
m_socket(0)
{
}

SocketServer::~SocketServer(void)
{
}

void SocketServer::start(int port)
{
m_port = port;

m_socket = socket(AF_INET, SOCK_STREAM, 0);
if(m_socket < 0)
throw Exception("Can't create socket");

struct sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = htons(INADDR_ANY);
serverAddr.sin_port = htons(port);

if(bind(m_socket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0)
throw Exception("Can't bind socket");

listen(m_socket, 1);

m_connectionThread = std::thread([this]() {
run();
});
}

void SocketServer::run(void)
{
while(true)
{
int client = accept(m_socket, NULL, NULL);
if(client < 0)
continue;

Socket *clientSocket = new Socket(client, this);
m_clients.push_back(std::shared_ptr<Socket>(clientSocket));
if(m_onClientConnectHandler)
m_onClientConnectHandler(clientSocket);
}
}

void SocketServer::sendToAll(const std::string &message)
{
for(auto client : m_clients)
client->sendString(message);
}

void SocketServer::messageReceived(Socket *socket, const std::string &message)
{
if(message == "close")
{
for(std::list<std::shared_ptr<Socket> >::iterator i = m_clients.begin();
i != m_clients.end(); i++)
{
if((*i)->getId() == socket->getId())
{
m_clients.erase(i);
return;
}
}
}

if(m_onMessageHandler)
m_onMessageHandler(socket, message);
}

0 comments on commit ad15c00

Please sign in to comment.