protected virtual async Task <bool> Receive(SocketStateObject socketState) { return(await Task.Run(() => { try { var didReceiveFullMessage = false; while (!didReceiveFullMessage) { var bytesRead = socketState.Socket.Receive(socketState.Buffer, 0, SocketStateObject.BufferSize, 0); if (bytesRead == 0) { continue; } socketState.sb.Append(Encoding.UTF8.GetString(socketState.Buffer, 0, bytesRead)); var content = socketState.sb.ToString(); if (!content.Contains("<EOF>")) { continue; } var msgs = content.Split("<EOF>"); foreach (var m in msgs) { if (string.IsNullOrEmpty(m)) { continue; // since <EOF> is at the end of string, so one split will always be empty } Console.WriteLine($"[{Name}] {socketState.Name} <- {m}"); socketState.LastMessage = m; MessageReceived?.Invoke(socketState.Name, m); socketState.sb.Clear(); didReceiveFullMessage = true; // TODO: Last element might not had <EOF> but we still considered it as full message. Append it again back to string builder and ignore in callbacks } } return true; } catch (Exception e) { Console.WriteLine($"[{Name}][Error] Connection unexpectedly closed: " + e.ToString()); return false; } })); }
protected virtual async Task <bool> Send(SocketStateObject socketState, string msg) { var tcs = new TaskCompletionSource <bool>(); var bytes = Encoding.UTF8.GetBytes(msg + "<EOF>"); try { Console.WriteLine($"[{Name}] {socketState.Name} -> {msg}"); socketState.Socket.BeginSend(bytes, 0, bytes.Length, 0, new AsyncCallback(SendCallback), (tcs, socketState)); } catch (Exception e) { Console.WriteLine($"[{Name}][Error] Failed to send data to socket: " + e.ToString()); tcs.SetResult(false); } return(await tcs.Task); }