TwitchDropsMiner icon indicating copy to clipboard operation
TwitchDropsMiner copied to clipboard

Connection problems?

Open Veyilla opened this issue 3 months ago • 28 comments

Hello,

Yesterday, I used the miner as normal and it ran without any problems. Since today, the GUI has been displaying "Reconnecting" every millisecond for all web sockets with "Connected". Initially, it connects normally, then the message described above appears. I am using the latest version of Windows 11.

I have already downloaded the current nightly version. Otherwise, I haven't changed anything and can't say what the problem is. However, the timer itself seems to be running. No error messages are displayed either. Clearing the cache did not change anything either.

I thought I'd better report it so that no problems arise.

Best regards, Veyilla

Veyilla avatar Nov 18 '25 11:11 Veyilla

Same issue here, the logs for the WebSockets show

 DEBUG:        Websocket[2] received: WSMessage(type=<WSMsgType.CLOSE: 8>, data=1009, extra='')
 2025-11-18 11:50:47.564:       WARNING:        Websocket[2] closed unexpectedly: 1009
Websocket[2] closed unexpectedly: 1009
 Websocket[2] reconnecting...
 2025-11-18 11:50:47.566:       WARNING:        Websocket[2] reconnecting...
 2025-11-18 11:50:47.581:          INFO:        Websocket[3] connected.


2025-11-18 11:50:51.215:         DEBUG:        Websocket[0] received: WSMessage(type=<WSMsgType.CLOSE: 8>, data=4010, extra='rate limit exceeded')
Websocket[0] received: WSMessage(type=<WSMsgType.CLOSE: 8>, data=4010, extra='rate limit exceeded')
Websocket[0] closed unexpectedly: 4010
2025-11-18 11:50:51.217:       WARNING:        Websocket[0] closed unexpectedly: 4010
025-11-18 11:50:51.219:       WARNING:        Websocket[0] reconnecting...
Websocket[0] reconnecting...

muffe avatar Nov 18 '25 11:11 muffe

Same here, its constantly reconnecting but watch time still seems to be counted. It started a few hours ago.

sk33ny avatar Nov 18 '25 12:11 sk33ny

Same here, behaviour started after the last update

Image

tiobane avatar Nov 18 '25 12:11 tiobane

Same here. Cloudflare related?

Coldblackice avatar Nov 18 '25 14:11 Coldblackice

Going by my logs and timezone the issue started at around 8PM Central yesterday night (so it was happening before cloudflare started having issues). First started with several closed unexpectedly: 1009 followed by eventually going to a closed unexpectedly: 4010 forever.

JourneyOver avatar Nov 18 '25 14:11 JourneyOver

Same, but watch time is still counted. Functionality seems fine but the logs are spammed.

ghost avatar Nov 18 '25 14:11 ghost

Functionality seems fine but the logs are spammed.

Are you going to permit it to continue in spite of this?

Coldblackice avatar Nov 18 '25 15:11 Coldblackice

Functionality seems fine but the logs are spammed.

Are you going to permit it to continue in spite of this?

I mean.. so far so good.. So I guess? No Bans yet lol

ghost avatar Nov 18 '25 15:11 ghost

Same here

anlan1210 avatar Nov 18 '25 17:11 anlan1210

I was experiencing this yesterday, this issue has now progressed to completely stopping the timer and halting all drops progress. Even reloading and restarting the app entirely do not resume progress, also many of the channels that have drops available are not working on the app and have an "x" on the drop tab when it should be an available channel. I had to switch back to using 165f9ec to get access to all available channels with drops but an still experiencing no drops progress at all on any..

whitebuffalo5 avatar Nov 18 '25 22:11 whitebuffalo5

Well I think I came up with a temporary solution (I believe should work (it at least seems to stop the constant disconnect/reconnect of the websockets every millisecond) though I do need to do more testing) until devil comes and pushes a new build himself with hopefully a much better fix than I came up with (which then I'll be reverting my solution and using his).

You can find my builds here -- https://github.com/JourneyDocker/TwitchDropsMiner / https://github.com/JourneyDocker/TwitchDropsMiner/releases/tag/dev-build

During load up it may take a slight bit longer before it starts farming things as the solution I came up with is just batching the LISTEN/UNLISTEN topic messages and added a small inter-batch delay.

I'm also not promising this is a good solution or will completely work and there may be some drawbacks to how it's done and such but it was just something that I quickly came up with to at least get things back up and running temporarily.

DO NOTE: There are several other changes in my versions of TDM, so it's not a 1:1 copy of Devils version, but it's extremely close.

JourneyOver avatar Nov 18 '25 22:11 JourneyOver

I have just recently ran into the issue posted in op where all my websockets keep switch from reconnecting to connected, repeatedly really fast non-stop.

LoneStrider18 avatar Nov 19 '25 04:11 LoneStrider18

I have just recently ran into the issue posted in op where all my websockets keep switch from reconnecting to connected, repeatedly really fast non-stop.

Because Twitch actively disconnected this websocket

Nek0Neko avatar Nov 19 '25 05:11 Nek0Neko

Hello,

First of all, I can't help but notice that Twitch definitely has some kind of rolling out system for this, because everything still works on my end - websocket status is just "Connected", and nothing described here is happening to me:

Image

That being said, I'd guess it's just a matter of time at this point.

Websocket problems are semi-expected, as there's a pending issue regarding moving over to the new websocket system: #755. I haven't given it much attention ever since creating the issue tbh, but it seems Twitch has decided to finally decommission the old websocket system after all. The websocket handler was due to a rewrite anyway (#110), so hopefully I can come up with a proper one this time.

DevilXD avatar Nov 19 '25 07:11 DevilXD

Hi @DevilXD , sorry if you already checked, but at least in my case, the permanent reconnecting only happens when i actively mine drops. When no drops are active, I also see connected 2/50 without any issues. But when I start mining drops, it instantly starts with the reconnecting. Maybe that helps.

tiobane avatar Nov 19 '25 09:11 tiobane

Hmm. I see.

@JourneyOver Does that solution actually work / prevent it from doing the reconnect thing? I mean, a rewrite into a new websocket system is still needed, but I could fast-patch it like that in the mean time.

DevilXD avatar Nov 19 '25 10:11 DevilXD

@DevilXD from what I can tell it does seem to be working for me (haven't experienced the whole reconnect issue this whole thread is about at least), I did have a few hiccups of other issues that went on but I'm not 100% sure if it was due to the change or something else going on at the time (over-mining a deltaforce campaign drop for a bit, and a Retrying a PersistedQueryNotFound for VideoPlayerStreamInfoOverlayChannel error a couple times at one point)..

The changes you need to make are just:

diff --git a/constants.py b/constants.py
index 30a95e9..3a4aedf 100644
--- a/constants.py
+++ b/constants.py
@@ -117,6 +117,8 @@ MAX_EXTRA_MINUTES = 15
 BASE_TOPICS = 2
 MAX_WEBSOCKETS = 8
 WS_TOPICS_LIMIT = 50
+# Number of topics to send per LISTEN/UNLISTEN message batch
+WEBSOCKET_TOPIC_BATCH_SIZE = 15
 TOPICS_PER_CHANNEL = 2
 MAX_TOPICS = (MAX_WEBSOCKETS * WS_TOPICS_LIMIT) - BASE_TOPICS
 MAX_CHANNELS = MAX_TOPICS // TOPICS_PER_CHANNEL
diff --git a/websocket.py b/websocket.py
index 2bf356f..dfe7627 100644
--- a/websocket.py
+++ b/websocket.py
@@ -12,7 +12,7 @@ import aiohttp
 
 from translate import _
 from exceptions import MinerException, WebsocketClosed
-from constants import PING_INTERVAL, PING_TIMEOUT, MAX_WEBSOCKETS, WS_TOPICS_LIMIT
+from constants import PING_INTERVAL, PING_TIMEOUT, MAX_WEBSOCKETS, WS_TOPICS_LIMIT, WEBSOCKET_TOPIC_BATCH_SIZE
 from utils import (
     CHARS_ASCII,
     task_wrapper,
@@ -210,35 +210,44 @@ class Websocket:
         self.set_status(refresh_topics=True)
         auth_state = await self._twitch.get_auth()
         current: set[WebsocketTopic] = set(self.topics.values())
-        # handle removed topics
+        # handle removed topics (with batching)
         removed = self._submitted.difference(current)
         if removed:
             topics_list = list(map(str, removed))
             ws_logger.debug(f"Websocket[{self._idx}]: Removing topics: {', '.join(topics_list)}")
-            await self.send(
-                {
-                    "type": "UNLISTEN",
-                    "data": {
-                        "topics": topics_list,
-                        "auth_token": auth_state.access_token,
+            # send in batches
+            for i in range(0, len(topics_list), WEBSOCKET_TOPIC_BATCH_SIZE):
+                batch = topics_list[i : i + WEBSOCKET_TOPIC_BATCH_SIZE]
+                await self.send(
+                    {
+                        "type": "UNLISTEN",
+                        "data": {
+                            "topics": batch,
+                            "auth_token": auth_state.access_token,
+                        }
                     }
-                }
-            )
+                )
+                # be gentle on the server
+                await asyncio.sleep(0.05)
             self._submitted.difference_update(removed)
-        # handle added topics
+        # handle added topics (with batching)
         added = current.difference(self._submitted)
         if added:
             topics_list = list(map(str, added))
             ws_logger.debug(f"Websocket[{self._idx}]: Adding topics: {', '.join(topics_list)}")
-            await self.send(
-                {
-                    "type": "LISTEN",
-                    "data": {
-                        "topics": topics_list,
-                        "auth_token": auth_state.access_token,
+            for i in range(0, len(topics_list), WEBSOCKET_TOPIC_BATCH_SIZE):
+                batch = topics_list[i : i + WEBSOCKET_TOPIC_BATCH_SIZE]
+                await self.send(
+                    {
+                        "type": "LISTEN",
+                        "data": {
+                            "topics": batch,
+                            "auth_token": auth_state.access_token,
+                        }
                     }
-                }
-            )
+                )
+                # be gentle on the server
+                await asyncio.sleep(0.05)
             self._submitted.update(added)
 
     async def _gather_recv(self, messages: list[JsonType], timeout: float = 0.5):

Edit: @DevilXD So I just found an easier way to temporarily fix this as well instead of sending batch requests like I had tried previously. change the WS_TOPICS_LIMIT https://github.com/DevilXD/TwitchDropsMiner/blob/master/constants.py#L119 to 25 and it seems to stop the issue as well. It seems the only acceptable number at the moment is 25 (so half of what the default is currently) anything higher and you start running into the websocket issues again that this issue thread is about.

EDIT2: The edit I posted above about the WS_TOPICS_LIMIT seems to work somewhat, but 25 is still a little too high as every so often you still run into the reconnect issue on at least 1 websocket out of the 7, you could probably lower the number a bit more but I'm not 100% sure on what changing that value is exactly affecting other than the amount of websockets connected. The best solution so far seems to still possibly be the batching of the LISTEN/UNLISTEN topic messages and added a small inter-batch delay.

Edit3: If you prefer going to WS_TOPICS_LIMIT route instead, it seems like the sweet spot to set it at might be at 20. At least from my testing so far I haven't ran into any websockets sitting there constantly reconnecting with the 1009, 4010 errors yet like I was with one of them every so often when I tried 25.

JourneyOver avatar Nov 19 '25 13:11 JourneyOver

Some GQL operations have an internal batch limit of 20 at a time. If I had to guess, Twitch made it so that the websocket can sub 20 topics at a time as well. The current code can send up to the limit of them, so all 50 at once.

DevilXD avatar Nov 19 '25 19:11 DevilXD

I added some simple chunk batching with 20 at a time (https://github.com/DevilXD/TwitchDropsMiner/commit/5d7a697c2be9d0e816b40f54c6bc52c4073838ed), and did a quick test that filled up all topic slots. Looked like nothing out of the ordinary, so I guess it works?

DevilXD avatar Nov 19 '25 20:11 DevilXD

Yea I'd say they for sure changed the topic amount you can send or something, the first change (the whole batching method) I made I let run overnight and didn't really have any issues other than the ones I mentioned above, the new method with lowering the WS_TOPICS_LIMIT I set it to 20 before leaving for work and 5 hours later it still seems to be running like a champ as well (both these methods have been tested on two different accounts (my main twitch account and my test account). So I think it's safe to say you could probably choose either method and be fine if you want to just get something out quickly while you work on the whole rewrite of the websocket.

JourneyOver avatar Nov 19 '25 20:11 JourneyOver

It seems we've posted at the same time =) I just did the change, so you could test if that works. It seemed to do just fine when I tested it, but I haven't done a test from before the change, so I can't compare it. I guess I could undo the change if I really wanted to test this myself, but I'd rather hear about it from others at this point.

DevilXD avatar Nov 19 '25 20:11 DevilXD

Yep :P I'll test things out and report back here soon ^^

JourneyOver avatar Nov 19 '25 20:11 JourneyOver

Well so far so good with the change ^^ all websockets are at 50/50 each, no reconnecting issues yet and I've done a couple reloads (which usually would quickly trigger the reconnecting problems when I was testing the WS_TOPICS_LIMIT stuff earlier) so I think for now this will at least be a good temporary fix until you can get the rewrite of the websocket done. I'll continue testing it over the course of the day and report back tonight on if anything has changed or not.

JourneyOver avatar Nov 19 '25 21:11 JourneyOver

Well for an update, 9 hours later and everything is still working perfectly. So yep I think I'll call the temp fix good for now.

JourneyOver avatar Nov 20 '25 06:11 JourneyOver

5d7a697 working for me. Thanks for getting on to it so quick.

Pyro2677 avatar Nov 20 '25 07:11 Pyro2677

Just a note - this is a temporary solution. If Twitch decides to suddenly axe-out the entire websocket connection, then we're kinda screwed. Getting a websocket rewrite ready will take at least a few days, during which time the miner will remain inoperative.

I took this friday off, so I'll have some time to look into it this weekend.

DevilXD avatar Nov 20 '25 12:11 DevilXD

So the problem with reconnecting the websocket is related to the Twitch?

glowxx avatar Nov 20 '25 15:11 glowxx

Well, yes. None of the recent changes have caused this - Twitch themselves did. Twitch changes things constantly, so the miner won't work forever without adjustments either.

DevilXD avatar Nov 21 '25 13:11 DevilXD

最近的几次更新都无法使用,开发者是怎么使用的呢,连接数50的问题,以及打开登陆后无法关闭的问题

zhilings avatar Jan 07 '26 07:01 zhilings

@zhilings 看 #877.

DevilXD avatar Jan 07 '26 11:01 DevilXD