3

What I want to do is set up an XMPP receiver using the Slixmpp library which listens for messages throughout the script execution. I think the threading library might provide a solution so tried that. This script is for an online PvP game and I need to receive information from the opponent continuously.

This is the code I have tried:

import time
import threading as td
import slixmpp as slix
import logging
import asyncio

my_jid = "test@xmpp.jp"
my_pass = "test"

class receiver(slix.ClientXMPP):
    def __init__(self, jid, password):
        slix.ClientXMPP.__init__(self, jid, password)
        self.add_event_handler("session_start", self.start)
        self.add_event_handler("message", self.message)

    def start(self, event):
        self.send_presence()
        self.get_roster()

    def message(self, msg):
        if msg['type'] in ('chat', 'normal'):
            msg.reply("Thanks for sending\n%(body)s" % msg).send()
            print(msg['body'])

def function():
    recv = receiver(my_jid, my_pass)
    recv.connect()
    recv.process()



newthread = threading.Thread(target=function)
logging.basicConfig(level="DEBUG", format='%(levelname)-8s %(message)s')


newthread.start()

input("Press Enter to continue")

This returns the following error:

Exception in thread Thread-1:
Press Enter to continueTraceback (most recent call last):
  File "C:\Program Files (x86)\Python37-32\lib\threading.py", line 917, in _bootstrap_inner
    self.run()
  File "C:\Program Files (x86)\Python37-32\lib\threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "C:/Users/dps/Documents/GitHub/Python-Problems/UltimateTicTacToe-scripts/xmppp.py", line 46, in good
    recv = receiver(my_jid, my_pass)
  File "C:/Users/dps/Documents/GitHub/Python-Problems/UltimateTicTacToe-scripts/xmppp.py", line 32, in __init__
    slix.ClientXMPP.__init__(self, jid, password)
  File "C:\Users\dps\venv\lib\site-packages\slixmpp\clientxmpp.py", line 70, in __init__
    BaseXMPP.__init__(self, jid, 'jabber:client', **kwargs)
  File "C:\Users\dps\venv\lib\site-packages\slixmpp\basexmpp.py", line 48, in __init__
    XMLStream.__init__(self, **kwargs)
  File "C:\Users\dps\venv\lib\site-packages\slixmpp\xmlstream\xmlstream.py", line 219, in __init__
    self.disconnected = asyncio.Future()
  File "C:\Program Files (x86)\Python37-32\lib\asyncio\events.py", line 644, in get_event_loop
    % threading.current_thread().name)
RuntimeError: There is no current event loop in thread 'Thread-1'.
  • *Slixmpp library which listens for messages throughout the script execution using threading library* - Are you sure it uses threading? Judging by the stack trace, it seems to be using asyncio, in which case it is not needed to create a new thread to run it. – user4815162342 May 27 '19 at 09:23
  • The problem is that when I call connect() and then process(), the code stops executing after that. It was a natural instinct to call upon threading to solve this problem. Also, I meant that I want to use the threading library and not that the slixmpp library uses it. Sorry for the confusion. – Samarth Singla May 27 '19 at 13:01
  • According to the [documentation](https://slixmpp.readthedocs.io/using_asyncio.html#running-the-event-loop), `process()` is just a thin wrapper around `loop.run_forever()`. If you don't want your code to stop, you should simply spawn a task (`async def`), and then call `loop.run_forever()` yourself. Then you won't need threads at all. – user4815162342 May 27 '19 at 13:20
  • Does that mean that when I will call `loop.run_forever()`, the loop will run in the background? – Samarth Singla May 27 '19 at 14:55
  • Can you please show a code example for this use-case? I am a beginner with coroutines... Thanks! – Samarth Singla May 27 '19 at 15:19
  • 1
    No, `run_forever()` blocks the current thread. But your *coroutines* will appear as if running in the background, because they will be suspended on (on every "blocking") `await` by the event loop. For an example, just look at any asyncio tutorial, e.g. https://realpython.com/async-io-python/ – user4815162342 May 27 '19 at 15:32

1 Answers1

0

In my case executing:

newthread.daemon = True

Before calling:

newthread.start()

Works as expected creating a non-blocking thread.

Erasmo
  • 84
  • 5