2020-09-23 09:37:18 +02:00
|
|
|
/**
|
|
|
|
* DServer
|
|
|
|
*
|
|
|
|
* Represents a server instance.
|
|
|
|
*
|
|
|
|
* Holds a list of DConnections,
|
|
|
|
* configuration parameters and
|
|
|
|
* more.
|
|
|
|
*/
|
|
|
|
|
|
|
|
module dnetd.dserver;
|
|
|
|
|
|
|
|
import core.thread : Thread;
|
|
|
|
import std.socket : Address, Socket;
|
|
|
|
import dnetd.dconnection;
|
2020-09-23 18:52:11 +02:00
|
|
|
import dnetd.dchannel;
|
|
|
|
import std.string : cmp;
|
|
|
|
import core.sync.mutex : Mutex;
|
2020-09-23 09:37:18 +02:00
|
|
|
|
|
|
|
public class DServer : Thread
|
|
|
|
{
|
|
|
|
/* The server's socket to bind, listen and accept connections from */
|
|
|
|
private Socket serverSocket;
|
|
|
|
|
|
|
|
/* Bind address */
|
|
|
|
private Address sockAddress;
|
|
|
|
|
|
|
|
|
2020-09-23 11:20:09 +02:00
|
|
|
/**
|
|
|
|
* Connection queue
|
|
|
|
*/
|
2020-09-23 09:37:18 +02:00
|
|
|
private DConnection[] connectionQueue;
|
2020-09-23 18:52:11 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Channels
|
|
|
|
*/
|
|
|
|
private DChannel[] channels;
|
|
|
|
private Mutex channelLock;
|
2020-09-23 09:37:18 +02:00
|
|
|
|
|
|
|
this(Address sockAddress)
|
|
|
|
{
|
|
|
|
/* Set the function to be called on thread start */
|
|
|
|
super(&dequeueLoop);
|
|
|
|
|
|
|
|
/* Set the listening address */
|
|
|
|
this.sockAddress = sockAddress;
|
|
|
|
|
|
|
|
/* Initialize the server */
|
|
|
|
init();
|
|
|
|
|
|
|
|
/* Start the server */
|
|
|
|
startServer();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void init()
|
|
|
|
{
|
|
|
|
/* Setup socket */
|
|
|
|
initNetwork();
|
|
|
|
|
|
|
|
/* Setup queues */
|
|
|
|
initQueues();
|
2020-09-23 18:52:11 +02:00
|
|
|
|
|
|
|
/* Setup locks */
|
|
|
|
initLocks();
|
2020-09-23 09:37:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates the socket, binds it
|
|
|
|
* to the given address
|
|
|
|
*/
|
|
|
|
private void initNetwork()
|
|
|
|
{
|
|
|
|
/* Create the socket */
|
|
|
|
serverSocket = new Socket();
|
|
|
|
|
|
|
|
/* Bind the socket to the given address */
|
|
|
|
serverSocket.bind(sockAddress);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates all needed queues
|
|
|
|
* and their mutexes
|
|
|
|
*/
|
|
|
|
private void initQueues()
|
|
|
|
{
|
|
|
|
/* TODO: Implement me */
|
|
|
|
}
|
2020-09-23 18:52:11 +02:00
|
|
|
|
|
|
|
private void initLocks()
|
|
|
|
{
|
|
|
|
/* Initialioze the channel lock */
|
|
|
|
channelLock = new Mutex();
|
|
|
|
}
|
2020-09-23 09:37:18 +02:00
|
|
|
|
|
|
|
private void startServer()
|
|
|
|
{
|
|
|
|
/* Start the connection dequeue thread */
|
|
|
|
start();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void dequeueLoop()
|
|
|
|
{
|
|
|
|
/* Start accepting-and-enqueuing connections */
|
|
|
|
serverSocket.listen(0); /* TODO: Linux be lile, hehahahhahahah who gives one - I give zero */
|
|
|
|
|
|
|
|
while(true)
|
|
|
|
{
|
|
|
|
/* Dequeue a connection */
|
|
|
|
Socket socket = serverSocket.accept();
|
|
|
|
|
|
|
|
/* Spawn a connection handler */
|
2020-09-23 18:52:11 +02:00
|
|
|
DConnection connection = new DConnection(this, socket);
|
2020-09-23 09:37:18 +02:00
|
|
|
|
|
|
|
/* Add to the connection queue */
|
|
|
|
connectionQueue ~= connection;
|
|
|
|
}
|
|
|
|
}
|
2020-09-23 18:52:11 +02:00
|
|
|
|
|
|
|
public void addChannel(DConnection causer, DChannel channel)
|
|
|
|
{
|
|
|
|
/* Lock the channels list */
|
|
|
|
channelLock.lock();
|
|
|
|
|
|
|
|
channels ~= channel;
|
|
|
|
|
|
|
|
/* TODO: Use causer */
|
|
|
|
|
|
|
|
/* Unlock the channels list */
|
|
|
|
channelLock.unlock();
|
|
|
|
}
|
|
|
|
|
|
|
|
public DChannel getChannelByName(string channelName)
|
|
|
|
{
|
|
|
|
/* Lock the channels list */
|
|
|
|
channelLock.lock();
|
|
|
|
|
|
|
|
foreach(DChannel currentChannel; channels)
|
|
|
|
{
|
|
|
|
if(cmp(currentChannel.getName(), channelName) == 0)
|
|
|
|
{
|
|
|
|
return currentChannel;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Unlock the channels list */
|
|
|
|
channelLock.unlock();
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
2020-09-23 09:37:18 +02:00
|
|
|
}
|