Skip to content Skip to sidebar Skip to footer

C-python Asyncio: Running Discord.py In A Thread

I have to launch discord.py in a separate thread since I can't block my main thread. It is a game server C/Python 3.7 (ubuntu 18) C code: int pysDiscord_Init; ... PyObject *psv_di

Solution 1:

Answering my own question:

I should thank this source asyncio-you-are-a-complex-beast where I finally found a solution. The final working code looks like this:

import discord
import asyncio
from threading import Thread


client = discord.Client()


definit():
    loop = asyncio.get_event_loop()
    loop.create_task(client.start(TOKEN))
    Thread(target=loop.run_forever).start()


@client.eventasyncdefon_message(message):
    if message.author == client.user:
        returnprint("on_message content: %s, channel: %s" % (message.content, message.channel))
    await message.channel.send('Hello!')


@client.eventasyncdefon_ready():
    print("Discord bot logged in as: %s, %s" % (client.user.name, client.user.id))

My main mistake was that for the game I compiled and used the latest rewrite version while inside the system over the pip I got 0.16.12 and read the documentation for 0.16.12 while I had to look at discord.py.rewrite (for example inside on_message I used wrong client.send_message while I had to use message.channel.send)

Solution 2:

I had a similar edge case (not really the intended use of asyncio but what the hell) where I needed to Thread the discord.py instance.

I ended up modifying your solution with the following:

classdiscordHost(discord.Client):
    asyncdefon_ready(self):
        print(f'{DThread.discord_client.user} has connected.')

classThreader(Thread):
    def__init__(self):
        Thread.__init__(self)
        self.loop = asyncio.get_event_loop()
        self.start()

    asyncdefstarter(self):
        self.discord_client = discordHost()
        await self.discord_client.start(DISCORD_TOKEN)

    defrun(self):
        self.name = 'Discord.py'

        self.loop.create_task(self.starter())
        self.loop.run_forever()

ifnot'Discord.py'in [t.name for t in tenumerate()]:
    DThread = Threader()

This does more or less the same thing, but I've subclassed Thread and subclassed discord.Client to more easily work with the outcome of the two.

The only caveat here, is that asyncio.get_event_loop() has to be called beforeThread.start(), otherwise it gets confused and losses it's context of the main thread.

Post a Comment for "C-python Asyncio: Running Discord.py In A Thread"