1 /*
2  *  Copyright (C) 2011-2016  OpenDungeons Team
3  *
4  *  This program is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef ODSOCKETSERVER_H
19 #define ODSOCKETSERVER_H
20 
21 #include "ODSocketClient.h"
22 
23 #include <SFML/Network.hpp>
24 
25 #include <string>
26 
27 class ODPacket;
28 
29 class ODSocketServer
30 {
31     public:
32         ODSocketServer();
33         ~ODSocketServer();
34 
35         bool isConnected();
36 
37         // Data Transimission
38         virtual bool createServer(int listeningPort);
39         virtual void stopServer();
40 
41     protected:
42         /*! \brief Function called when a new client connects. If the server returns an ODSocketClient,
43          *! it will be added to the client list
44          */
45         virtual ODSocketClient* notifyNewConnection(sf::TcpListener& sockListener) = 0;
46 
47         /*! \brief Function called when a client sends a message. As this function is called
48          * from the doTask context, it shall return as soon as possible (we should not send
49          * a message and wait actively for its answer). The proper way of communicating should be :
50          * 1 - read the message
51          * 2 - If needed, send something (answer or new question)
52          * 3 - Save somewhere if we are waiting for something from the client
53          * 4 - Return from the function. When new data will be available, notifyClientMessage
54          *     will be called again
55          * If the function returns false, the client will be removed from the list and properly deleted
56          */
57         virtual bool notifyClientMessage(ODSocketClient *sock) = 0;
58 
59         /*! \brief Main function task. Checks if a new client connects. If so, notifyNewConnection
60          * will be called with the client socket. If it returns true, the client is saved in the
61          * client list. If not, the client is discarded. doTask also checks if a connected client sent
62          * a message. If so, calls notifyClientMessage with the client socket.
63          * If timeoutMs = 0, this function will never return. Otherwise, it will always return after
64          * timeoutMs milliseconds, even if new clients connected or clients are sending messages.
65          */
66         void doTask(int timeoutMs);
67         std::vector<ODSocketClient*> mSockClients;
68         virtual void serverThread() = 0;
69         sf::Thread* mThread;
70 
71     private:
72         sf::TcpListener mSockListener;
73         sf::SocketSelector mSockSelector;
74         sf::Clock mClockMainTask;
75         bool mIsConnected;
76 };
77 
78 #endif // ODSOCKETSERVER_H
79 
80