bwmarrin / discordgo

(Golang) Go bindings for Discord
BSD 3-Clause "New" or "Revised" License
5.08k stars 808 forks source link

Testing discordgo with quic-go #1067

Closed galpt closed 2 years ago

galpt commented 2 years ago

I'm currently testing to combine quic-go with discordgo.

It seems some features work well but some do not. I'm also adding a fallback method so the bot can switch back to normal http2

// set custom http client and user agent (fallback to http2)
s.Client = httpclient
s.UserAgent = discordUA

// set custom http client and user agent (use http3 for some features that seem to work)
s.Client = h3client
s.UserAgent = discordUA

I found that some of these don't work (or sometimes they just misbehave). Some other functions might not work as expected too with HTTP, but since I only tested these, I'm still not sure about it.

s.ChannelMessageDelete(m.ChannelID, m.ID)
s.ChannelMessageSendEmbed(m.ChannelID, &aoiEmbeds)
s.MessageReactionAdd(m.ChannelID, m.ID, customEmojiSlice[customEmojiIdx])
s.GuildEmojis(getGuilds[guildIdx].ID)
s.GuildBans(guildID)

Some can be fixed by switching to http2, but sometimes switching back to http2 doesn't fix the issue. All functions work as expected when using websocket, but sometimes they misbehave when using http.

I know that we're not supposed to use http3 for production yet, but it's interesting to know that http3 transport works with discord too.

I wonder if it's considered as a bug when we use HTTP or did I miss something? Some extra info that might caused the issue to occur

tlsConf = &tls.Config{
    InsecureSkipVerify:          true,
    PreferServerCipherSuites:    true,
    SessionTicketsDisabled:      false,
    DynamicRecordSizingDisabled: false,
}

discordUA = "DiscordBot (https://github.com/bwmarrin/discordgo, v" + discordgo.VERSION + ") Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"

h1Tr = &http.Transport{
    DisableKeepAlives:      false,
    DisableCompression:     false,
    ForceAttemptHTTP2:      true,
    TLSClientConfig:        tlsConf,
    TLSHandshakeTimeout:    20 * time.Second,
    ResponseHeaderTimeout:  20 * time.Second,
    IdleConnTimeout:        60 * time.Minute,
    ExpectContinueTimeout:  1 * time.Second,
    MaxIdleConns:           10000,
    MaxIdleConnsPerHost:    1000,
    MaxConnsPerHost:        0,
    MaxResponseHeaderBytes: 32 << 10,
    WriteBufferSize:        32 << 10,
    ReadBufferSize:         32 << 10,
}

httpclient = &http.Client{
    Timeout:   60 * time.Minute,
    Transport: h1Tr,
}
galpt commented 2 years ago

I managed to fix it. Closing this issue now.

jalavosus commented 2 years ago

@galpt https://xkcd.com/979/ please don't be that guy. Can you explain how you managed to fix it?

galpt commented 2 years ago

@galpt https://xkcd.com/979/ please don't be that guy. Can you explain how you managed to fix it?

There were various things that were causing the issue. In my case, if it's just to send/receive data from/to discord using http3, then it'll simply work since discord depends a lot on cloudflare and cloudflare supports http3.

So I'm just using http3 for known servers that support it and use http2 as the fallback. (Problem solved if you're not using any sharding on your bot)

Also, I was using shards and somehow it caused functions to misbehave while they were working normally without sharding. Either this problem's from discord or from the shards implementation or probably it's just how sharding works and you need to adjust your code to function properly with sharding.

I had to move some code from bottom to top and vice versa until the bot worked as expected. Probably it's still not very clear to you but that's just what happened.