Reputation: 73
I don't know why but it keeps disconnecting. Sometimes it works for 1 hour, sometimes less and sometimes 2.5 hour-ish
import aiohttp
import asyncio
import json
import datetime, time
token = "123"
payload = {
'op': 2,
"d": {
"token": token,
"properties": {
"$os": "windows",
"$browser": "chrome",
"$device": 'pc'
}
}
}
last_sequence = "null"
async def main():
global last_sequence
session = aiohttp.ClientSession()
async with session.ws_connect('wss://gateway.discord.gg/?v=9&encording=json') as ws:
async for msg in ws:
data = json.loads(msg.data)
if data["op"] == 10: # Hello
await ws.send_json(payload)
# (Keeps the connection alive!)
asyncio.ensure_future(heartbeat(ws, data['d']['heartbeat_interval']))
elif data["op"] == 11: # Heartbeat ACK
#print("Heartbeat Received")
pass
elif data["op"] == 0: # Dispatch
try:
if data['d']['guild_id']==("669653521007902751") and data['d']['channel_id']==("669653521007902766"):
print(f"{data['d']['content']}")
last_sequence = data['s']
#print(data)
except:
pass
elif data["op"] == 3: # Presence Update
print("This is OP 3", data)
elif data["op"] == 4: # Voice State Update
print("This is OP 4", data)
elif data["op"] == 6: # Resume
print("This is OP 6", data)
elif data["op"] == 7: # Reconnect, i don't know how this works. I was just testing it.
await ws.send_json(
{"op": 6,
"d": {
"token":token,
"session_id": "null",
"seq": last_sequence
}})
print("This is OP 7", data)
elif data["op"] == 8: # Request Guild Members
print("This is OP 8", data)
elif data["op"] == 9: # Invalid Session
print("This is OP 9", data)
else:
print("What happened?", data)
#await session.close()
async def heartbeat(ws, interval):
while True:
await asyncio.sleep(interval / 1000) # seconds
await ws.send_json({
"op": 1, # Heartbeat
"d": last_sequence
})
print("Heartbeat Sent", last_sequence, time.strftime("%H:%M:%S", time.localtime()))
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
The error is
This is OP 7 {'t': None, 's': None, 'op': 7, 'd': None} Task was destroyed but it is pending! task: <Task pending name='Task-4' coro=<heartbeat() running at C:\Users\test\Desktop\Discord_Test\aio_test.py:83> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x00000214675B83D0>()]>>
Upvotes: 3
Views: 5393
Reputation: 21
Your error is that on an opcode 7 you are not disconnecting. You are just sending the resume string. you need to FULLY close the connection, and reconnect THEN after you get the server hello, send the resume(with a valid session_id and seq, they cannot be null). the server is closing your connection because your sending data to it after it told you to disconnect/reconnect(opcode 7) then your code is crashing because it has a task waiting for the heartbeat when the server kills your connection.
EDIT: (You should store the session_id from the server READY event(after you identify(op 2), and the last "seq" number you received from the server to use them in your resume string for resuming.)
Discord now requires you to periodically reconnect(for no outwardly apparent reason) by sending you an opcode "7". You should make your bot disconnect and reconnect when you receive that opcode. You should then attempt to identify(opcode 2) or resume(opcode 6).
If you have a valid "session_id" and "seq" number you should send a resume(op 6), if not you should identify(op 2). Discord may respond to a resume with an opcode 9(invalid session) and set "d" to true(can try and resume) or false(need to re-identify). You should resend the correct opcode (2 or 6) depending on if d is true or false.(You supposedly do NOT need to disconnect/reconnect on an opcode 9, just resend the identify/resume payload)
https://discord.com/developers/docs/topics/gateway#reconnect
Additional information: https://github.com/discord/discord-api-docs/commit/d4ccc367966eef95b05c8e82ca6cac333ab586db
Lately I have been having another issue where discord is always returning an opcode 9 when I send a resume.
So discord sends an op 7 to my client. I reconnect and send an op 6 after I received the server hello opcode(10). I then immediately, and always receive an opcode 9 even though I am absolutely 100% sending the correct payload data etc for an opcode 6. I then have to resend an opcode 2(identify) and start a new session.
It seems odd discord is now making me restart my session every single time I try and resume after I get an opcode 7, and reconnect. If anyone knows why this is happening that would be nice. but it isn't a terribly big deal since i don't think discord would ever make you re-identify enough times to reach the 1000 identifys per day limit
(I have tried various lengths of time waiting before reconnecting btw)
Upvotes: 2