Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // NetServer.h
- // OsciStudio
- //
- // Created by Hansi on 07.06.15.
- //
- //
- #ifndef __OsciStudio__NetServer__
- #define __OsciStudio__NetServer__
- #include "ofMain.h"
- #include "Poco/Net/TCPServer.h"
- #include "Poco/Net/TCPServerParams.h"
- #include "Poco/Net/TCPServerConnectionFactory.h"
- #include "Poco/Net/TCPServerConnection.h"
- #include "Poco/Net/Socket.h"
- #include <mutex>
- class NetClient;
- struct NetStatus{
- NetStatus() : client(NULL),online(false){}
- NetStatus( NetClient * client ) : client(client),online(true){}
- NetClient * client;
- bool online;
- };
- class NetMessage{
- public:
- NetMessage() : clientId(-1),str(""){};
- NetMessage(int clientId, string str) : clientId(clientId),str(str){};
- int clientId;
- string str;
- };
- // based on http://stackoverflow.com/questions/14632341/poconet-server-client-tcp-connection-event-handler
- class NetServer : public Poco::Net::TCPServerConnectionFactory{
- public:
- NetServer();
- void start( int port );
- void stop();
- NetMessage nextMessage();
- void send( int clientId, string message );
- Poco::Net::ServerSocket * socket;
- Poco::Net::TCPServer * server;
- private:
- Poco::Net::TCPServerConnection* createConnection(const Poco::Net::StreamSocket& socket);
- map<int,NetStatus> clientStatus;
- int nextClientId = 0;
- queue<NetMessage> messageQueue;
- std::mutex queueMutex;
- friend class NetClient;
- };
- class NetClient : public Poco::Net::TCPServerConnection{
- public:
- NetClient(NetServer & server, const Poco::Net::StreamSocket& s);
- void run();
- void send( string message );
- int id;
- bool die;
- NetServer &server;
- };
- #endif /* defined(__OsciStudio__NetServer__) */
- //
- // NetServer.cpp
- // OsciStudio
- //
- // Created by Hansi on 07.06.15.
- //
- //
- #include "NetServer.h"
- #include <algorithm>
- NetServer::NetServer() : socket(NULL),server(NULL){
- }
- void NetServer::start(int port){
- socket = new Poco::Net::ServerSocket(port);
- //Configure some server params.
- Poco::Net::TCPServerParams* pParams = new Poco::Net::TCPServerParams();
- pParams->setMaxThreads(4);
- pParams->setMaxQueued(4);
- pParams->setThreadIdleTime(100);
- //Create your server
- server = new Poco::Net::TCPServer(this, *socket, pParams);
- server->start();
- }
- void NetServer::stop(){
- if( socket != NULL ){
- socket->close();
- socket = NULL;
- }
- if( server != NULL ){
- server->stop();
- server = NULL;
- }
- // disconnect all clients that are still online
- for( int i = 0; i < nextClientId; i++ ){
- if( clientStatus[i].online ){
- clientStatus[i].client->die = false;
- }
- }
- }
- Poco::Net::TCPServerConnection* NetServer::createConnection(const Poco::Net::StreamSocket& socket)
- {
- return new NetClient(*this, socket);
- }
- NetMessage NetServer::nextMessage(){
- if( messageQueue.size() == 0 ){
- return NetMessage();
- }
- else{
- NetMessage message = messageQueue.front();
- lock_guard<mutex> lock(queueMutex);
- messageQueue.pop();
- return message;
- }
- }
- void NetServer::send( int clientId, string message ){
- if( clientStatus[clientId].online ){
- clientStatus[clientId].client->send(message);
- }
- }
- NetClient::NetClient(NetServer &server, const Poco::Net::StreamSocket& s) : Poco::Net::TCPServerConnection(s), die(false), id(server.nextClientId++), server(server){
- server.clientStatus[id] = NetStatus(this);
- }
- void NetClient::run(){
- cout << "New connection from: " << socket().peerAddress().host().toString() << endl << flush;
- bool isOpen = true;
- Poco::Timespan timeOut(10,0);
- unsigned char incommingBuffer[1000];
- stringstream message;
- while(isOpen && !die){
- if (socket().poll(timeOut,Poco::Net::Socket::SELECT_READ) == false){
- // just a poll timeout. no worries!
- // cout << "TIMEOUT!" << endl << flush;
- }
- else{
- int nBytes = -1;
- try {
- nBytes = socket().receiveBytes(incommingBuffer, sizeof(incommingBuffer));
- }
- catch (Poco::Exception& exc) {
- //Handle your network errors.
- cerr << "Network error: " << exc.displayText() << endl;
- isOpen = false;
- }
- if (nBytes==0){
- cout << "Client closes connection!" << endl << flush;
- isOpen = false;
- }
- else{
- //cout << "Receiving nBytes: " << nBytes << endl << flush;
- const unsigned char* start = incommingBuffer;
- const unsigned char* end = incommingBuffer + nBytes;
- while( start != end ){
- const unsigned char* match = std::find(start, end, '\n');
- string str = string(start,match);
- message << str;
- if( match != end ){
- server.queueMutex.lock();
- server.messageQueue.push(NetMessage(id,message.str()));
- server.queueMutex.unlock();
- message.str("");
- message.clear();
- start = match + 1;
- }
- else{
- start = end;
- }
- }
- }
- }
- }
- server.clientStatus[id].client = NULL;
- server.clientStatus[id].online = false;
- cout << "Connection finished!" << endl << flush;
- }
- void NetClient::send( string message ){
- socket().sendBytes(message.c_str(), message.length());
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement