If you put time.sleep(5) in conn.process() you will fall behind the Hello %d producer rather than processing the requests in parallel. If you put `await asyncio.sleep(5)` in there, however, you would actually be eligible for Little's Law and reap benefits of async/await and concurrent coroutines. As it is, your application gains nothing from the complexity though you could at least do other things on the main thread while waiting for the 1 byte. (so it'll only hitch when it receives a message woo)
It appears that you have misunderstood your own concurrency model. In fact you have only 2 long-running tasks: 1 that publishes "Hello %d" every 3ish seconds and 1 that awaits 1 byte to kick off a stack that consumes your cpu until the request is completely materialized, handled and responded to, then waits for another byte. It is single threaded you are very right there, more right that I suspect you intended.
There are 5 switches to the main task to do a blocking publish and 5 switches to the recvTrigger task to pass 1 materialized byte into a blocking handler.
There is not a lot of task switching and not a lot of asynchrony. You have 1 degree of handler parallelism here due to your blocking handler loop. Sprinkle in some time.sleep() to convince yourself of this. If you are actually shooting for 1 degree of parallelism, why are you even using asyncio? Just use a thread, block it to your heart's content and plop messages onto a queue that your message handler loop consumes from. That way you at least get a little pressure relief architecturally and other people who look at your code will understand it because it uses 1 consistent paradigm.
Good luck to you. I sincerely hope others are not led into fear of async by this. It is easy stuff; and like class member methods vs. module static methods, the calling convention is a little different. It's so straightforward though!
Right, so tl;dr: Python's async/await is pythonic, fine and generally the right way to do responsive apps in 2020 (some cpu-bound apps may require threading to be responsive, but Python isn't usually the best choice for heavily cpu-bound applications either). Fighting against it while trying to benefit from it is subtle and will most likely confuse even the author.
If you want a responsive python app, you probably want to use async libraries and idioms. If you want a serial python app (as you have here), you probably want to use serial libraries and idioms (as you have not done here).
Bonus tl;dr: Answering the topic's question of how to avoid async def, there are 2 ways:
A. Do not do anything that involves waiting. (network activity, DMA send/receive, file access, etc.) Then you won't be tempted to make your app responsive because it'll be responsive already.
B. Do not use async. Figure out a different way to keep your app responsive.