Like this!
After many studies, this is what I found:
First of all, we got a connection method.
private readonly StreamSocket _clientSocket; private bool _connected; private DataReader _dataReader; public string Hostname { get; set; } public int Port { get; set; } public Credentials Credentials; public readonly string Channel; public async Task < bool > Connect() { if (_connected) return false; var hostname = new HostName(Hostname); await _clientSocket.ConnectAsync(hostname, Port.ToString()); _connected = true; _dataReader = new DataReader(_clientSocket.InputStream) { InputStreamOptions = InputStreamOptions.Partial }; ReadData(); return true; }
To read the data that we receive through StreamSocket, we create the ReadData () method and make it recursive so that we continue to receive data:
async private void ReadData() { if (!_connected || _clientSocket == null) return; uint s = await _dataReader.LoadAsync(2048); string data = _dataReader.ReadString(s); if (data.Contains("No ident response")) SendIdentity(); if (Regex.IsMatch(data, "PING :[0-9]+\\r\\n")) ReplyPong(data); ReadData(); }
Now we have two new methods: SendIdentity(); and ReplyPong(string message); Usually the IRC server will ping you, here you should respond with an awning, for example:
private void ReplyPong(string message) { var pingCode = Regex.Match(message, "[0-9]+"); SendRawMessage("PONG :" + pingCode); }
And we also need to send our identity when the server is ready for it, for example:
private void SendIdentity() { if (Credentials.Nickname == string.Empty) Credentials.Nickname = Credentials.Username; SendRawMessage("NICK " + Credentials.Nickname); SendRawMessage("USER " + Credentials.Username + " " + Credentials.Username + " " + Credentials.Username + " :" + Credentials.Username); if (Credentials.Password != String.Empty) SendRawMessage("PASS " + Credentials.Password); } public class Credentials { public string Nickname { get; set; } public string Username { get; set; } public string Password { get; set; } public Credentials(string username, string password = "", string nickname = "") { Username = username; Password = password; Nickname = nickname; } }
Finally, we have our SendRawMessage(); method SendRawMessage(); that sends data to the server.
async private void SendRawMessage(string message) { var writer = new DataWriter(_clientSocket.OutputStream); writer.WriteString(message + "\r\n"); await writer.StoreAsync(); await writer.FlushAsync(); writer.DetachStream(); if (!_closing) return; _clientSocket.DisposeSafe(); _connected = false; }
I almost forgot the dispose function, which you can call when you want to close the stream :)
public void Dispose() { SendRawMessage("QUIT :"); _closing = true; }
This will send a final message indicating that we are leaving, and since now the close is now true, after that the thread will be deleted.