C# Can't answer on PING

Hello, I’m making bot on C# and I can’t figure out, why it still disconnects me after PING, here is my response

if (raw.Contains("PING"))
{
             SendIrcMessage("PONG :tmi.twitch.tv");
             BeginInvoke(new Action(() => textBox1.Text += $"{DateTime.Now.Hour}:{DateTime.Now.Minute} ping {raw}\r\n"));
             return;
}

public void SendIrcMessage(string message)
{
    outputStream.WriteLine(message);
    outputStream.Flush();
}

TcpClient tcpClient = new TcpClient("irc.chat.twitch.tv", 6667);
StreamWriter outputStream = new StreamWriter(tcpClient.GetStream());

I saw some topics with same problem so it seems that my response is correct but it doesn’t work for some reason.
Yes, I do it with winforms for my own reasons.
And I don’t want to use twitchlib (btw I can’t use it with wf) or any else lib.

Yes, I have pingsender

public void PingSender(StreamWriter outputStream)
{
    while (true)
    {
        outputStream.WriteLine("PING :tmi.twitch.tv");
        outputStream.Flush();
        Thread.Sleep(300000);
    }
}

And sorry, how did you put code in such window?

Indent by four spaces or

Unless you are threading somewhere your code will be stuck in the while (true)/sleep loop and not process anything else no?

Task.Run(() => Functions.PingSender(outputStream));

Yes, it’s a thread.

I’m sorry if I gave not enough information. But it looks like I did everything right but respose to a PIGN disconnects me anyway.

I’m confused why you’re sending a PING message to twitch since those should only ever be received by a client, not sent. However your response message looks like it’s formatted correctly. I would check to make sure that StreamWriter properly appends \r\n since any other combination violates the IRC spec and might be seen as a garbage message. Are you able to successfully send other messages with your SendIrcMessage(...) function?

For reference, this is my writer which works as of last night. (Also in C#)

public void
Pong(string trailing = "")
{
    string message = "PONG";
    if (trailing.IsValid())
    {
        message += " :" + trailing;
    }

    Send(message);
}

public void
Send(string format, params object[] arguments)
{
    ExceptionUtil.ThrowIfInvalid(format, nameof(format));

    string message = !arguments.IsValid() ? format : string.Format(format, arguments);
    if (!CanSend(message))
    {
        return;
    }

    byte[] bytes = Encoding.UTF8.GetBytes(message + "\r\n");            
    stream.Write(bytes, 0, bytes.Length);
    stream.Flush();

    OnDataSent.Raise(this, new DataEventArgs(bytes, message));
}

If I can send Ping to twitch or message to twitch chat that makes my SendIrcMessage(...) function correct? stream.WriteLine() adds \r\n, I guess or I wouldn’t be able to connect.

outputStream.WriteLine("CAP REQ :twitch.tv/tags");
outputStream.WriteLine("CAP REQ :twitch.tv/commands"); 
outputStream.WriteLine("CAP REQ :twitch.tv/membership"); 
outputStream.WriteLine("PASS " + password);
outputStream.WriteLine("NICK " + username);
outputStream.WriteLine("USER " + username + " 8 * :" + username);
foreach(string channel in Channels) outputStream.WriteLine("JOIN #" + channel);           
outputStream.Flush();

And that works fine. I can send Ping (btw I don’t know the reason too, but moderator said that I should, I mean, I can check connection with twitch through pings).
Your stream is StreamWriter?

Hm, interesting. Since you are able to connect I guess it can’t be writer or your function.

My stream is just a normal Stream that is instantiated using a NetworkStream.

Is it possible, that my Brandmauer or anivirus blocks something? I just can’t understand the problem. And I don’t even know if twitch server received my pong.

You see the ping in your textBox1? How is raw populated (how do you read)?

Yep, just a standart ping (all pongs before ping from twitch)

Are you actually sending the full line :tmi.twitch.tv PONG tmi.twitch.tv :irc.twitch.tv to Twitch, or only parts of that?

I tried several variants :tmi.twitch.tv PONG tmi.twitch.tv :irc.twitch.tv, PONG tmi.twitch.tv, PONG irc.twitch.tv. Did I miss something?

The first message include what’s called a “prefix”. It’s not prohibited by the Spec, but per the IRC spec:

Clients should not use prefix when sending a message from
themselves; if they use a prefix, the only valid prefix is the
registered nickname associated with the client. If the source
identified by the prefix cannot be found from the server’s internal
database, or if the source is registered from a different link than
from which the message arrived, the server must ignore the message
silently.

So essentially if you do send a prefix, it must only ever be :your_nick_here COMMAND :message\r\n

To be safe, I would just omit the prefix entirely. Your PONG response would then just look like:

PONG :tmi.twitch.tv\r\n

In your case, the \r\n is covered by your StreamWriter.Writeline(...)

Just PONG works with TMI. You don’t need anything special around it.

1 Like

Nope, neither PONG :tmi.twitch.tv\r\n, not PONG works for me. Btw I have another bot that works fine but on Node.js with tmi.js so everything should be alrigth, but still disconnects the c# one.

Just because I’m a moderator doesn’t make me correct.

I have found that at times Twitch can leave it’s ping pongs a little spaced out. So I send my own ping’s in order to help keep the connection alive.

Off hand I forget what the IRC spec says on that matter. But it seems to work well for my code and usecase.

So if you say that sendin your Pings to server is enough and that means my Pings didn’t count?

I am wondering if you are not reading chat and then you are being disconnected because the “send message to client buffer” becomes too large and Twitch disconnects you.