Merge pull request #7 from SemvdH/fix-async-stuff

merge Fix async stuff into master
This commit is contained in:
SemvdH
2020-10-22 17:02:30 +02:00
committed by GitHub
4 changed files with 59 additions and 29 deletions

View File

@@ -2,8 +2,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
using System.Windows;
using static SharedClientServer.JSONConvert; using static SharedClientServer.JSONConvert;
namespace Client namespace Client
@@ -24,6 +26,7 @@ namespace Client
public Callback OnLobbiesListReceived; public Callback OnLobbiesListReceived;
public LobbyJoinCallback OnLobbyJoinSuccess; public LobbyJoinCallback OnLobbyJoinSuccess;
public Callback OnLobbiesReceivedAndWaitingForHost; public Callback OnLobbiesReceivedAndWaitingForHost;
public Callback OnServerDisconnect;
public LobbyCallback OnLobbyCreated; public LobbyCallback OnLobbyCreated;
public LobbyCallback OnLobbyLeave; public LobbyCallback OnLobbyLeave;
private ClientData data = ClientData.Instance; private ClientData data = ClientData.Instance;
@@ -40,45 +43,60 @@ namespace Client
private void OnConnect(IAsyncResult ar) private void OnConnect(IAsyncResult ar)
{ {
Debug.Write("finished connecting to server"); Debug.Write("finished connecting to server");
this.tcpClient.EndConnect(ar); try
this.stream = tcpClient.GetStream(); {
OnSuccessfullConnect?.Invoke(); this.tcpClient.EndConnect(ar);
SendMessage(JSONConvert.ConstructUsernameMessage(username)); this.stream = tcpClient.GetStream();
this.stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(OnReadComplete),null); OnSuccessfullConnect?.Invoke();
SendMessage(JSONConvert.ConstructUsernameMessage(username));
this.stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(OnReadComplete),null);
} catch (Exception e)
{
Debug.WriteLine("Can't connect, retrying...");
tcpClient.BeginConnect("localhost", Port, new AsyncCallback(OnConnect), null);
}
} }
private void OnReadComplete(IAsyncResult ar) private void OnReadComplete(IAsyncResult ar)
{ {
if (ar == null || (!ar.IsCompleted) || (!this.stream.CanRead) || !this.tcpClient.Client.Connected) if (ar == null || (!ar.IsCompleted) || (!this.stream.CanRead) || !this.tcpClient.Client.Connected)
return; return;
try
int amountReceived = stream.EndRead(ar);
if (totalBufferReceived + amountReceived > 1024)
{ {
throw new OutOfMemoryException("buffer too small"); int amountReceived = stream.EndRead(ar);
}
Array.Copy(buffer, 0, totalBuffer, totalBufferReceived, amountReceived); if (totalBufferReceived + amountReceived > 1024)
totalBufferReceived += amountReceived; {
throw new OutOfMemoryException("buffer too small");
}
int expectedMessageLength = BitConverter.ToInt32(totalBuffer, 0); Array.Copy(buffer, 0, totalBuffer, totalBufferReceived, amountReceived);
totalBufferReceived += amountReceived;
while (totalBufferReceived >= expectedMessageLength) int expectedMessageLength = BitConverter.ToInt32(totalBuffer, 0);
while (totalBufferReceived >= expectedMessageLength)
{
// we have received the complete packet
byte[] message = new byte[expectedMessageLength];
// put the message received into the message array
Array.Copy(totalBuffer, 0, message, 0, expectedMessageLength);
handleData(message);
totalBufferReceived -= expectedMessageLength;
expectedMessageLength = BitConverter.ToInt32(totalBuffer, 0);
}
ar.AsyncWaitHandle.WaitOne();
stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(OnReadComplete), null);
} catch (IOException e)
{ {
// we have received the complete packet Debug.WriteLine("[CLIENT] server not responding! got error: " + e.Message);
byte[] message = new byte[expectedMessageLength]; OnServerDisconnect?.Invoke();
// put the message received into the message array
Array.Copy(totalBuffer, 0, message, 0, expectedMessageLength);
handleData(message);
totalBufferReceived -= expectedMessageLength;
expectedMessageLength = BitConverter.ToInt32(totalBuffer, 0);
} }
ar.AsyncWaitHandle.WaitOne();
stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(OnReadComplete), null);
} }
private void handleData(byte[] message) private void handleData(byte[] message)
@@ -162,12 +180,14 @@ namespace Client
{ {
Debug.WriteLine("[CLIENT] sending message " + Encoding.ASCII.GetString(message)); Debug.WriteLine("[CLIENT] sending message " + Encoding.ASCII.GetString(message));
stream.BeginWrite(message, 0, message.Length, new AsyncCallback(OnWriteComplete), null); stream.BeginWrite(message, 0, message.Length, new AsyncCallback(OnWriteComplete), null);
} }
private void OnWriteComplete(IAsyncResult ar) private void OnWriteComplete(IAsyncResult ar)
{ {
Debug.WriteLine("[CLIENT] finished writing"); Debug.WriteLine("[CLIENT] finished writing");
stream.EndWrite(ar); stream.EndWrite(ar);
stream.Flush();
} }
} }
} }

View File

@@ -35,6 +35,10 @@ namespace Client
client = ClientData.Instance.Client; client = ClientData.Instance.Client;
client.OnLobbiesListReceived = updateLobbies; client.OnLobbiesListReceived = updateLobbies;
client.OnLobbyLeave = leaveLobby; client.OnLobbyLeave = leaveLobby;
client.OnServerDisconnect = () =>
{
Environment.Exit(0);
};
OnHostButtonClick = new RelayCommand(hostGame); OnHostButtonClick = new RelayCommand(hostGame);
@@ -58,12 +62,10 @@ namespace Client
private void becomeHostForLobby(int id) private void becomeHostForLobby(int id)
{ {
Debug.WriteLine($"got host succes with data {id} "); Debug.WriteLine($"got host succes with data {id} ");
wantToBeHost = true; wantToBeHost = true;
wantToBeHostId = id; wantToBeHostId = id;
client.OnLobbiesReceivedAndWaitingForHost = hostLobbiesReceived; client.OnLobbiesReceivedAndWaitingForHost = hostLobbiesReceived;
} }
private void hostLobbiesReceived() private void hostLobbiesReceived()

View File

@@ -15,6 +15,7 @@ using static SharedClientServer.JSONConvert;
namespace Server.Models namespace Server.Models
{ {
public delegate void Callback();
class ServerClient : ObservableObject class ServerClient : ObservableObject
{ {
private TcpClient tcpClient; private TcpClient tcpClient;
@@ -24,6 +25,7 @@ namespace Server.Models
private int totalBufferReceived = 0; private int totalBufferReceived = 0;
public User User { get; set; } public User User { get; set; }
private ServerCommunication serverCom = ServerCommunication.INSTANCE; private ServerCommunication serverCom = ServerCommunication.INSTANCE;
private Callback OnMessageReceivedOk;
/// <summary> /// <summary>
@@ -94,6 +96,7 @@ namespace Server.Models
} }
catch (IOException e) catch (IOException e)
{ {
Debug.WriteLine("[SERVERCLIENT] Client disconnected! exception was " + e.Message);
tcpClient.Close(); tcpClient.Close();
ServerCommunication.INSTANCE.ServerClientDisconnect(this); ServerCommunication.INSTANCE.ServerClientDisconnect(this);
} }
@@ -158,6 +161,10 @@ namespace Server.Models
case JSONConvert.RANDOMWORD: case JSONConvert.RANDOMWORD:
//Flag byte for receiving the random word. //Flag byte for receiving the random word.
break; break;
case JSONConvert.MESSAGE_RECEIVED:
// we now can send a new message
OnMessageReceivedOk?.Invoke();
break;
default: default:
Debug.WriteLine("[SERVER] Received weird identifier: " + id); Debug.WriteLine("[SERVER] Received weird identifier: " + id);
break; break;

View File

@@ -18,6 +18,7 @@ namespace SharedClientServer
public const byte LOBBY = 0x03; public const byte LOBBY = 0x03;
public const byte CANVAS = 0x04; public const byte CANVAS = 0x04;
public const byte RANDOMWORD = 0x05; public const byte RANDOMWORD = 0x05;
public const byte MESSAGE_RECEIVED = 0x06;
public enum LobbyIdentifier public enum LobbyIdentifier
{ {