BrandonPotter / SimpleTCP

Straightforward .NET library to handle the repetitive tasks of spinning up and working with TCP sockets (client and server).
Apache License 2.0
363 stars 108 forks source link

[Usage Help] - Event DelimiterDataReceived keep alive? #33

Closed XavierBrassoud closed 6 years ago

XavierBrassoud commented 6 years ago

Hi,

Thank's for this nice library.

I'm confronted to usage problem. I setup a new instance of SimpleTcp in my client library. When DelimiterDataReceived is reached a second time, nothing happens... it's seem my client is disconnected.

To be sure the second data is never send to the server i try to throw a new Exception error but... the exception never appear...

Format of Server protocol (Yes my client can send data like he want...): [1 char flag][0x00]

Here is the code into the client:

```c# Session session = new Session("127.0.0.1", 4321); session.Connect(); session.Account.Logon("AccountTest", "TestPassword"); ```

Here is my library (simplified as possible):

```c# using SimpleTCP; namespace ClientLibrary { public class Session { // Network private string address; private int port; internal SimpleTcpClient client; // Core public Account Account; private PacketManager packetManager; internal bool isConnected = false; public Session(string address, int port) { this.address = address; this.port = port; client = new SimpleTcpClient { Delimiter = 0x00 }; client.DelimiterDataReceived += Client_DelimiterDataReceived; Account = new Account(this); packetManager = new PacketManager(this); } private void Client_DelimiterDataReceived(object sender, Message packet) { packetManager.Process(packet.MessageString); } public void Connect() { client.Connect(address, port); } } public class Account { private Session session; public Account(Session session) { this.session = session; } public void Logon(string account, string password) { if (session.isConnected) session.client.WriteLine(account + '|' + password); } } public class PacketManager { private Session session; public PacketManager(Session session) { this.session = session; } public void Process(string data) { string flag = data[0]; switch (flag) { case 'A': // Received from Server "Hello" { session.isConnected = true; break; } // this case is never reached case 'B': // Received from Server "Ok, it's your credentials" { session.Send("Yeah I received your message! But it's a dream..."); throw new Exception("This exception never appear"); break; } } } } } ```

Here is log of the server:

``` DEBUG : Server : Client connected : 127.0.0.1 DEBUG : Server : Sended -> 'A' DEBUG : Server : Received from Client -> "AccountTest|TestPassword" DEBUG : Server : Sended -> 'B' DEBUG : Server : Client disconnected : 127.0.0.1 ```


Ok I don't know if is it a bug in your library or a pebcak problem, so... if you can help me I thank you a lot in advance, but if not you can close this issue, I would try again and again to performe a good library, thanksfully to your!

XavierBrassoud commented 6 years ago

Hello,

I've solved my problem, I've added a List<string> "bufferPacket" property into my main class Session, which is provided by the byte.MessageString of DelimiterDataReceived event. Then I've added a async method which read the List<string> "bufferPacket" and process Task asynchronously.

Here is the code into the client:

```c# Session session = new Session("127.0.0.1", 4321); await session.ConnectAsync(); await session.Account.LogonAsync("AccountTest", "TestPassword"); ```

Here is the code into my library:

```c# using SimpleTCP; namespace ClientLibrary { public class Session { // Network private string address; private int port; internal SimpleTcpClient client; private List bufferPacket; // Core public Account Account; private PacketManager packetManager; internal bool isConnected = false; public Session(string address, int port) { this.address = address; this.port = port; client = new SimpleTcpClient { Delimiter = 0x00 }; client.DelimiterDataReceived += Client_DelimiterDataReceived; Account = new Account(this); packetManager = new PacketManager(this); } private void Client_DelimiterDataReceived(object sender, Message packet) { bufferPacket.Add(packet.MessageString); } public async Task ConnectAsync() { client.Connect(address, port); await GetReplyAsync(); } internal async Task GetReplyAsync() { for (int i = 0; i < bufferPacket.Count(); i++) { processTask = packetManager.Process(bufferPacket[i]); try { await processTask; } catch (AggregateException ae) { throw ae.Flatten(); } } bufferPacket.Clear(); } } public class Account { private Session session; public Account(Session session) { this.session = session; } public async Task LogonAsync(string account, string password) { if (session.isConnected) { session.client.WriteLine(account + '|' + password); await session.GetReplyAsync(); } } } public class PacketManager { private Session session; public PacketManager(Session session) { this.session = session; } public void Process(string data) { string flag = data[0]; switch (flag) { case 'A': // Received from Server "Hello" { session.isConnected = true; break; } // this case is never reached case 'B': // Received from Server "Ok, it's your credentials" { session.Send("Yeah I received your message!"); throw new Exception("This exception now appear! :D"); break; } } } } } ```


This issue is solved ! (sorry for opened this here)...