/// <summary>
/// Child thread function.
/// Handles a connection with a single client.
/// </summary>
/// <param name="client">The TcpClient object</param>
private void HandleConnectionWithClient(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream networkStream = tcpClient.GetStream();
IPAddress address = ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address;
Log("Remote client connected", address, 0);
object message = Message.Recieve(networkStream);
while (tcpClient.Connected && message != null)
{
if (message is string && message as string == "Test")
{
// A test message was recieved. Send a response back.
Log("Recieved a connection test request", address, 1);
Message.TestMsg(networkStream);
}
else if (message is AuthRequest)
{
// An AuthRequest was receieved. Authenticate the user and reply with a UserToken.
AuthRequest req = message as AuthRequest;
Log("Recieved an authentication request", address, 1);
UserToken token = null;
if (req.register)
{
Log(" Registering New User: "******" Registration Successful", address, 2);
}
else
{
Log(" Registration Failed", address, 2);
}
} catch (DatabaseException ex) {
Log("DATABASE ERROR: Registration could not proceed", address, 0);
Log(ex.Message, 0);
}
}
else
{
Log(" Authenticating User: "******" Authentication Successful", address, 2);
}
else
{
Log(" Authentication Failed", address, 2);
}
} catch (DatabaseException ex) {
Log("DATABASE ERROR: Authentication could not proceed", address, 0);
Log(ex.Message, 0);
}
}
Message.Send(networkStream, new AuthResponse(token));
}
else if (message is TokenVerifyRequest)
{
// A TokenVerifyRequest was recieved. Test the token for validity.
Log("Recieved a token verification request", address, 1);
TokenVerifyRequest req = message as TokenVerifyRequest;
Log(" User: "******" Expires: " + req.token.expires, address, 2);
Log(" Token: " + req.token.token, address, 2);
try {
bool valid;
if (database.VerifyToken(req.token) != 0)
{
Log(" Verification Successful", address, 2);
valid = true;
}
else
{
Log(" Verification Failed", address, 2);
valid = false;
}
Message.Send(networkStream, new TokenVerifyResponse(valid));
} catch (DatabaseException ex) {
Log("DATABASE ERROR: Could not process request", address, 0);
Log(ex.Message, 0);
Message.Send(networkStream, new BBResponse("Database", "An unknown database error occured. Could not process request."));
}
}
else if (message is BBRequest)
{
try {
// A BBRequest was recieved. Process the request
BBRequest bbmessage = message as BBRequest;
Log("Received a " + bbmessage.requestType + " request", address, 1);
// Authenticate the user
int userID;
if (bbmessage.requestType.userToken == null)
{
Log(" No user supplied. Processing as anonymous.", address, 2);
userID = -1;
}
else
{
Log(" Username: "******" Expires: " + bbmessage.requestType.userToken.expires, address, 2);
Log(" Token: " + bbmessage.requestType.userToken.token, address, 2);
userID = database.VerifyToken(bbmessage.requestType.userToken);
}
if (userID == 0)
{
Log(" User Authentication failed", address, 1);
Message.Send(networkStream, new BBResponse());
}
else
{
if (bbmessage.requestType is BBRequest.UpDownVote)
{
// Upload and vote on a song
BBRequest.UpDownVote req = bbmessage.requestType as BBRequest.UpDownVote;
Log(" " + (req.vote ? "Upvote" : "Downvote") + " Request", address, 2);
Log(" ID: " + req.song.ID, address, 3);
Log(" Genre: " + req.song.genre, address, 3);
Log(" Tempo: " + req.song.tempo, address, 3);
Log(" Seed: " + req.song.seed, address, 3);
SongParameters song = database.VoteOnSong(req.song, req.vote, userID);
Message.Send(networkStream, new BBResponse(song));
Log(" Response has ID of " + song.ID + " and score of " + song.score, address, 2);
}
else if (bbmessage.requestType is BBRequest.RequestScore)
{
// Request the score of a song
BBRequest.RequestScore req = bbmessage.requestType as BBRequest.RequestScore;
Log(" ID: " + req.song.ID, address, 3);
Log(" Genre: " + req.song.genre, address, 3);
Log(" Tempo: " + req.song.tempo, address, 3);
Log(" Seed: " + req.song.seed, address, 3);
SongParameters song = database.RefreshSong(req.song);
Message.Send(networkStream, new BBResponse(song));
Log(" Response has ID of " + song.ID + " and score of " + song.score, address, 2);
}
else if (bbmessage.requestType is BBRequest.RequestSongs)
{
// Request a list of songs
BBRequest.RequestSongs req = bbmessage.requestType as BBRequest.RequestSongs;
List <SongParameters> songList = database.GetSongList(req.num, req.genre, req.username);
Message.Send(networkStream, new BBResponse(songList));
Log(" Returned " + songList.Count + " songs", address, 2);
}
else
{
Log("BBREQUEST ERROR: Unknown BBRequest type '" + bbmessage.GetType() + "'", address, 0);
Message.Send(networkStream, new BBResponse("BBRequest", "Unknown BBRequest type '" + bbmessage.GetType() + "'"));
}
}
} catch (DatabaseException ex) {
Log("DATABASE ERROR: Could not process request", address, 0);
Log(ex.Message, 0);
Message.Send(networkStream, new BBResponse("Database", "An unknown database error occured. Could not process request."));
} catch (System.IO.IOException ex) {
Log("IO ERROR: Could not send response", address, 0);
Log(ex.Message, 0);
}
}
else
{
Log("Unknown request type '" + message.GetType() + "'", address, 0);
}
message = Message.Recieve(networkStream);
}
Log("Remote client disconnected", address, 0);
tcpClient.Close();
}