284 lines
9.9 KiB
TeX
284 lines
9.9 KiB
TeX
\documentclass[10pt]{book}
|
|
\usepackage{xcolor}
|
|
\usepackage{listings}
|
|
|
|
\definecolor{mGreen}{rgb}{0,0.6,0}
|
|
\definecolor{mGray}{rgb}{0.5,0.5,0.5}
|
|
\definecolor{mPurple}{rgb}{0.58,0,0.82}
|
|
\definecolor{backgroundColour}{rgb}{0.95,0.95,0.92}
|
|
|
|
\lstdefinestyle{CStyle}{
|
|
backgroundcolor=\color{backgroundColour},
|
|
commentstyle=\color{mGreen},
|
|
keywordstyle=\color{magenta},
|
|
numberstyle=\tiny\color{mGray},
|
|
stringstyle=\color{mPurple},
|
|
basicstyle=\footnotesize,
|
|
breakatwhitespace=false,
|
|
breaklines=true,
|
|
captionpos=b,
|
|
keepspaces=true,
|
|
numbers=left,
|
|
numbersep=5pt,
|
|
showspaces=false,
|
|
showstringspaces=false,
|
|
showtabs=false,
|
|
tabsize=2,
|
|
language=C
|
|
}
|
|
|
|
\begin{document}
|
|
|
|
\tableofcontents
|
|
|
|
\chapter{Overview}
|
|
|
|
Welcome to BMASockets Core Server. The server core was developed to
|
|
provide a quick path to developing your server requirements on a high
|
|
performance Linux platform network. The design can be used to develop
|
|
customing gaming platforms or you can use any of the existing protocol
|
|
session handlers to implement your own compact high performance server
|
|
using existing known protocols.
|
|
|
|
The BMASockets Core Server provides existing handlers for the
|
|
following protocols:
|
|
|
|
\begin{enumerate}
|
|
\item HTTP and HTTPS
|
|
\item SIP and SIPS
|
|
\item HTTP streaming server
|
|
\item HTTP Web Sockets handler
|
|
\end{enumerate}
|
|
|
|
The focus of the design is to extend the capabilities of two core
|
|
objects to create the interface to your own implementations.
|
|
|
|
\chapter{Linux epoll Interactions}
|
|
|
|
Linux provides an set of system calls to open a socket that is used to
|
|
manage the networking requests for multiple sockets from a single
|
|
process. You can find plenty of materials on the internet on epoll and
|
|
how this function works. The Core Server is designed around the
|
|
concept of the socket (BMASocket) and the handling of accepting
|
|
connections on a binding socket and managing the individual client
|
|
sockets that are \emph{accepted}.
|
|
|
|
TCP and UDP are both supported by the Core Server. The differences in
|
|
managing these socket types is abstracted through the use of the
|
|
sessions object (BMASession). This abstract class cannot be
|
|
instantiated but is used instead to extend into a customizable session
|
|
object that will be used to manage the protocol for the connected
|
|
session. At the session level there is no difference between the
|
|
underlying socket type, whether it be UDP or TCP.
|
|
|
|
The TCP side of the fence incorporates the connection oriented design
|
|
to provide the sessions to the higher levels. Each client represents a
|
|
socket that has connected through the \emph{bind} and \emph{accept}
|
|
system call method. Conversing with a client in a TCP session returns
|
|
the appropriate data through that socket connection.
|
|
|
|
The UDP side of the fence incorporates session objects that are based
|
|
upon connectionless packets sent to a single receiving socket. The UDP
|
|
server (BMAUDPServerSocket) maintains a list of sessions which are
|
|
managed according the sending address of the packets received. Each remote
|
|
address represents a different client and interactions back to the
|
|
session are sent through the single socket to the corresponding remote
|
|
address. This provides a seamless session to the higher level
|
|
activities of the server.
|
|
|
|
The interface provided through the session appears the same regardless
|
|
of the socket type. This affords the developer the opportunity to
|
|
write UDP or TCP socket handlers with no knowledge of the those
|
|
protocols. Building a game server would be the same for either type
|
|
and both types could be enabled simultaneously.
|
|
|
|
\chapter{The Core Server}
|
|
|
|
In order to provide flexibility to the Core Server several design
|
|
factors have been put in place. Creating a new server that handles a
|
|
custom protocol requires the extension of only two objects. These are
|
|
the BMATCPServerSocket or BMAUDPServerSocket, depending on the type
|
|
desired, and the BMASession object.
|
|
|
|
When extending the BMATCPServerSocket all that is needed is to
|
|
override the getSocketAccept() method to return an extended TCPSession
|
|
object. This basically tells the server to spawn a new session of a
|
|
particular type for every new connection to the bound TCP port.
|
|
|
|
Data received in the session can be delivered to the application
|
|
using two different modes. The LINE mode will call the onLineReceived()
|
|
handler for each line received in the buffer. The line termination can
|
|
be LF or CRLF combination and is filtered from the string handed to
|
|
the onLineReceived() method call. The BLOCK mode will call the
|
|
onBlockReceived() handler for each blockSize bytes received in the
|
|
data buffer.
|
|
|
|
The extended TCPSession object can override the onLineReceived()
|
|
and/or the onBlockReceived() methods to handle the incoming requests
|
|
for the socket. An entire application structure could be built upon
|
|
this mechanism to handle complex protocols with the client.
|
|
|
|
\chapter{Sample Server Example}
|
|
|
|
This chapter specifies the approach to extending and creating a customized server. This example is focusing on a server used in gaming environments. The gaming clients connect to the server to interact with other clients.
|
|
|
|
The BMA Server Core can provide all the features needed of a multiport high demand server. The implementation of epoll combined with the ability to manage job control load through the use of multiple threads provides a robust request handling environment for all socket based architectures.
|
|
|
|
As the BMAEPoll object is started it will spawn the specified number of threads which will in turn begin the socket handling functions necessary to manage all network requests in the program. The main program itself is not used but must not be allowed to return or end so it can be used to handle other non sockets related processing in the application.
|
|
|
|
Additionally, this server example provides a console that is accessible through a Telnet style server and does not currently incorporate any encryption (TLS) or login authentication. This will be changing in the future.
|
|
|
|
\section{The Server}
|
|
|
|
The server provides a few interesting features that may not be readily apparent when reading through the documentation.
|
|
|
|
Since each BMATCPServerSocket also inherits from BMACommand the server can override a routine to output data relivant to the type of server you are creating.
|
|
|
|
When creating the server you are asked to provide a command name as a parameter. The inheriting server object can then obtain a list of connected clients from a console object by typing this name in on a command line.
|
|
|
|
\begin{lstlisting}[style=CStyle]
|
|
#ifndef BMAConsoleServer_h__
|
|
#define BMAConsoleServer_h__
|
|
|
|
#include "includes"
|
|
#include "BMATCPServerSocket.h"
|
|
#include "BMACommand.h"
|
|
class BMATCPSocket;
|
|
|
|
class BMAConsoleServer : public BMATCPServerSocket {
|
|
|
|
public:
|
|
BMAConsoleServer(BMAEPoll &ePoll, std::string url, short int port);
|
|
~BMAConsoleServer();
|
|
|
|
BMASession * getSocketAccept();
|
|
|
|
void registerCommand(BMACommand &command);
|
|
|
|
int processCommand(BMASession *session) override; ///<Output the consoles array to the console.
|
|
|
|
std::vector<BMACommand *> commands;
|
|
|
|
};
|
|
|
|
#endif
|
|
\end{lstlisting}
|
|
|
|
\begin{lstlisting}[style=CStyle]
|
|
#include "BMAEPoll.h"
|
|
#include "BMAConsoleServer.h"
|
|
#include "BMAConsoleSession.h"
|
|
#include "BMACommand.h"
|
|
|
|
BMAConsoleServer::BMAConsoleServer(BMAEPoll &ePoll, std::string url, short int port)
|
|
: BMATCPServerSocket(ePoll, url, port, "consoles") {
|
|
// ePoll.log.registerConsole(*this);
|
|
// ePoll.log.write(0) << "BMAConsole initializing..." << endl;
|
|
}
|
|
|
|
BMAConsoleServer::~BMAConsoleServer() {
|
|
|
|
}
|
|
|
|
BMASession * BMAConsoleServer::getSocketAccept() {
|
|
return new BMAConsoleSession(ePoll, *this);
|
|
}
|
|
|
|
void BMAConsoleServer::registerCommand(BMACommand &command) {
|
|
commands.push_back(&command);
|
|
}
|
|
|
|
int BMAConsoleServer::processCommand(BMASession *session) {
|
|
|
|
std::stringstream out;
|
|
int sequence = 0;
|
|
|
|
for(BMASession *session : sessions) {
|
|
out << "|" << ++sequence;
|
|
out << "|" << session->getClientAddressAndPort();
|
|
out << "|" << std::endl;
|
|
}
|
|
|
|
session->write((char *)out.str().c_str(), out.str().size());
|
|
|
|
return 0;
|
|
}
|
|
\end{lstlisting}
|
|
|
|
\section{The Session}
|
|
|
|
\begin{lstlisting}[style=CStyle]
|
|
#include "includes"
|
|
#include "BMAEPoll.h"
|
|
#include "BMAMP3File.h"
|
|
#include "BMAConsoleServer.h"
|
|
#include "BMATCPServerSocket.h"
|
|
#include "BMAStreamServer.h"
|
|
#include "BMAHTTPServer.h"
|
|
#include "BMASIPServer.h"
|
|
#include "BMAHTTPRequestHandler.h"
|
|
#include "BMAMP3StreamContentProvider.h"
|
|
#include "BMATimer.h"
|
|
|
|
int main(int argc, char **argv) {
|
|
|
|
std::string ipAddress = "0.0.0.0";
|
|
|
|
BMAEPoll ePoll;
|
|
ePoll.start(4, 1000);
|
|
|
|
//----------------------
|
|
// Testing TCP server.
|
|
//----------------------
|
|
|
|
BMATCPServerSocket tcpServer(ePoll, ipAddress, 1028, "users");
|
|
|
|
//------------------------
|
|
// MP3 Streaming Server
|
|
//------------------------
|
|
|
|
BMAStreamServer stream(ePoll, ipAddress, 1032, "listeners");
|
|
BMAMP3File tester(stream, "../extravaganza.mp3");
|
|
|
|
//--------------
|
|
// HTTP Server
|
|
//--------------
|
|
|
|
BMAHTTPServer http(ePoll, ipAddress, 1080, "http");
|
|
BMAHTTPRequestHandler handler1(http, "/");
|
|
|
|
//-------------
|
|
// SIP Server
|
|
//-------------
|
|
|
|
BMASIPServer sip(ePoll, ipAddress, 5061, "sip");
|
|
|
|
//-------------------------------------------------------------
|
|
// Console controller so the program can be monitored through
|
|
// a telnet session. BMATCPServerSocket can be registered as
|
|
// a command and will report its status when the command is
|
|
// entered on the console.
|
|
//-------------------------------------------------------------
|
|
|
|
BMAConsoleServer console(ePoll, ipAddress, 1027);
|
|
console.registerCommand(ePoll);
|
|
console.registerCommand(console);
|
|
console.registerCommand(http);
|
|
console.registerCommand(sip);
|
|
console.registerCommand(stream);
|
|
|
|
ePoll.start(4, 1000);
|
|
|
|
while(true)
|
|
sleep(300);
|
|
|
|
ePoll.stop();
|
|
|
|
}
|
|
\end{lstlisting}
|
|
|
|
\end{document}
|
|
|
|
|
|
|