I'm trying to create a simple WebSocket server using websockets module in Python.
My task is to create a WebSocket server that sends a message to all the clients that are listening to it. The problem is that everytime a client disconnects, websockets launches an exception (ConnectionClosedOK or ConnectionClosedError, depending of what happened) that I need to catch because I have to unregister the clients that have disconnected so that the WebSocket stops to send messages in the ether (and stopping the WebSocket server throwing these exceptions everytime that he tries to send a message to a closed client).
Here's the server's code:
async def foo_call():
await asyncio.sleep(3)
print('Hi!')
async def register(websocket):
users.add(websocket)
await notify_users()
async def unregister(websocket):
users.remove(websocket)
async def start(websocket, path):
await register(websocket)
try:
await foo_call()
except websockets.ConnectionClosedError:
await unregister(websocket)
# WebSocket clients that are listening this WebSocket server
users = set()
# Open WebSocket server
start_server = websockets.serve(start, "localhost", 8765)
# Run asyncio event loop
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
And here's the traceback:
Task exception was never retrieved
future: <Task finished coro=<WebSocketCommonProtocol.send() done, defined at /home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py:521> exception=ConnectionClosedError('code = 1006 (connection closed abnormally [internal]), no reason',)>
Traceback (most recent call last):
File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py", line 827, in transfer_data
message = await self.read_message()
File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py", line 895, in read_message
frame = await self.read_data_frame(max_size=self.max_size)
File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py", line 971, in read_data_frame
frame = await self.read_frame(max_size)
File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py", line 1051, in read_frame
extensions=self.extensions,
File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/framing.py", line 105, in read
data = await reader(2)
File "/usr/lib/python3.6/asyncio/streams.py", line 672, in readexactly
raise IncompleteReadError(incomplete, n)
asyncio.streams.IncompleteReadError: 0 bytes read on a total of 2 expected bytes
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py", line 555, in send
await self.ensure_open()
File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py", line 803, in ensure_open
raise self.connection_closed_exc()
websockets.exceptions.ConnectionClosedError: code = 1006 (connection closed abnormally [internal]), no reason
I don't really understand how can I catch those exceptions thrown by websockets module.
Related
I have a Python server that needs to upgrade an existing connection to TLS. The connection is created by asyncio.start_server.
It needs to upgrade to TLS in the middle of a connection because it is emulating MySQL's wire protocol.
The project is mysql-mimic. Here is what I've tried so far: https://github.com/kelsin/mysql-mimic/pull/17
There appears to be a some kind of sequencing issue: if the client starts TLS before the server, the server never completes the handshake.
Here is a script to reproduce the issue:
import asyncio
import ssl
# Self-signed certs for testing
CERT_FILE = "cert.pem"
CERT = """
-----BEGIN CERTIFICATE-----
MIIEIzCCAwugAwIBAgIUUMROPFb3ZMssWfl9/tJVMB0Zl0owDQYJKoZIhvcNAQEL
BQAwgZ8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
DA1TYW4gRnJhbmNpc2NvMRQwEgYDVQQKDAtteXNxbC1taW1pYzEUMBIGA1UECwwL
bXlzcWwtbWltaWMxFDASBgNVBAMMC215c3FsLW1pbWljMSEwHwYJKoZIhvcNAQkB
FhJleGFtcGxlQGRvbWFpbi5jb20wIBcNMjIxMDI0MTgyNzQ0WhgPMjEyMjA5MzAx
ODI3NDRaMIGfMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG
A1UEBwwNU2FuIEZyYW5jaXNjbzEUMBIGA1UECgwLbXlzcWwtbWltaWMxFDASBgNV
BAsMC215c3FsLW1pbWljMRQwEgYDVQQDDAtteXNxbC1taW1pYzEhMB8GCSqGSIb3
DQEJARYSZXhhbXBsZUBkb21haW4uY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAsnmS0k1Q0f+mv7izbT5K8zqYP54KwyW000qMhYLW/Ir5fGAw2QHg
Q1vMBY+1oaHcO1DxjriG4l8P8ho9AShAD63Q3PVUiy3Prxi3PaZ/jPsI5rN/8s7s
TXai6Po6gD56uYtZACl4cjF2ob3Vy/qzIPitW3D7UVEL+nqDEZUSmbFnT+NAMaCv
Bq+Zf94vQSpQXgUSbTNAuFqjwMLeb8VX31e5yFOvhRd1Y65MOwmeCX0hMZ+XtcPc
xtgCyQ9uT2OaKcqcngE/LtGnC4UJy0u5bcI8pPgwenGWNhQ6LrqLWAUizEXoprY8
PUVoE42Itm7j1ODKm71OpNPqEjXxvs924wIDAQABo1MwUTAdBgNVHQ4EFgQUSVIG
PQ1FTdvJeup85cCLpp/5wGIwHwYDVR0jBBgwFoAUSVIGPQ1FTdvJeup85cCLpp/5
wGIwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAJcoALjwItgWa
Qpr/hJCHhtf1gS6DCbtQoc+Owvz0iJkC+zqeaFlOYwVQz/n8iQ45g03cLMxHfMEv
lj1ctHfVGI+2exp2hesMmU+CT49D9qFS2vQnaKxkeUqv5ia2d+V49jE6fj3CxIPP
T3yI9+K2Ojx+7/WVVxCgz+eIZJbTCugoypDksldfuY4mx48E9qefOlBNcYyBzHt4
4iymCFFrfQHfMX+PnKDGHaoh/T/oZxdZRyDxNqTLfiyZ1PtAbueeT4Jf6CmamQZh
IadFPXnA1YlEqreMk6nDrF8pqgOosHIngLhhUXHAVj/Br3UaDTaUGzlrlL7rLpRL
oToCkplUgg==
-----END CERTIFICATE-----
"""
KEY_FILE = "key.pem"
KEY = """
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCyeZLSTVDR/6a/
uLNtPkrzOpg/ngrDJbTTSoyFgtb8ivl8YDDZAeBDW8wFj7Whodw7UPGOuIbiXw/y
Gj0BKEAPrdDc9VSLLc+vGLc9pn+M+wjms3/yzuxNdqLo+jqAPnq5i1kAKXhyMXah
vdXL+rMg+K1bcPtRUQv6eoMRlRKZsWdP40AxoK8Gr5l/3i9BKlBeBRJtM0C4WqPA
wt5vxVffV7nIU6+FF3Vjrkw7CZ4JfSExn5e1w9zG2ALJD25PY5opypyeAT8u0acL
hQnLS7ltwjyk+DB6cZY2FDouuotYBSLMReimtjw9RWgTjYi2buPU4MqbvU6k0+oS
NfG+z3bjAgMBAAECggEBAI1wPUO+k/soUByGImPDxyAE4p0gAUVv/2KnJL+11exj
sp23mV6Q1wpqmEAcCIQkQuUbG6PQZszFK1zhIFFndYU3aVuCbNKzpnAL9UO9TD4M
v5wcypxBEhG9oBNkIrJ5UUbzwL+ZHePZgTtitykk74qEqNXbrr9drFF/f5mSeyAi
nUkizI/aGJVp2+NVpsFvZd0M5gM1tEWoBq/5fny/b1oWM/blh1ZwWQII3bTcDABH
1h30oTuGWYyeQExUjiS4SDDJ8BH9PZxUGQhQsK1ZuJczJ5B+jh0OWicdD+P+V2EB
npoWQVHKwqwfDQisx2T04TAb65QcbM7V/EwgQPpcd5ECgYEA3bQbff5bIvbgJwCo
1bHxj3MMmu1Qs+Km9nR8FbEtFaF1lbXzPLCj98VDpT3tBNw4VwpbVYn5rd4ZSs6h
jlK2zEakFRvU/qgtTrUviW4oeSrEtUt8jI0QkdobUWPM8HuZih6Lgm5DTU6HwIBR
dxkhojx7c1zwSm66Bojvn/CjVakCgYEAzhWHAxkNAj97XvjUe9XsV41jiksheNS2
7vAm1PASq9MGFpSazq2NeXTxuChvMK8vN9r2FngnFKW4hLGMi8wpReT+S1C32sNP
ZWRq6w2JWgQvh7dNSNmn0mBc7zwUB6sFeS72q3Ge355dPJiuomRLxZmm+P3suHIV
b+4Fj6q0p6sCgYEAqj5EojJwn1+97pVGEJqM6N+qvUkgoJGaLkRyiGG+Qg7y8RyA
BImLz5ZuBHSSDhphNQ1h50SFMusKtvQHAPgpIKHaG898dnSEHh1pvHmXoLujw6eM
o40rPSSjt5MQa1YuJ+6eqHCtQ67a9YpThEYLGr6g+YxThISUWrJKd6HceskCgYB0
gWMUc0MRdEYQyOeHIsc8L+iINDU2FDtfFVE+rIJBtUkJ1vU1xpPmiCBnFiTWBxPQ
pe7dgQvG9nE8QwvLtJ3Yr767YWSvPh9SmNSBEeQGibs9JHmCp9niayve673/H8Y2
XkCBZ/iDPwpCyaZglAbqLRViSltbYtOPtaZbNAxxhQKBgH8Gj0yg3A5DwWEyeUKR
KJBS2rPiKgrhJs8Kd8GZZUb3H5WGqzfgrRK1p9j5Ug8UXSWbB9e5jg4ymVtcAAhc
tRz4rCvYNY8fHlA2TfzrOeEuuxtoMFyxd26eFjZvS/w2VdFrIQZbSvDkV4hMqhpS
CCslSFIIZOMCzqgQtM+NTQJ6
-----END PRIVATE KEY-----
"""
async def start_tls(reader, writer, sslcontext, server_side=False):
# Borrowed from https://stackoverflow.com/questions/62851407/how-do-i-enable-tls-on-an-already-connected-python-asyncio-stream
transport = writer.transport
protocol = transport.get_protocol()
loop = asyncio.get_event_loop()
new_transport = await loop.start_tls(
transport=transport,
protocol=protocol,
sslcontext=sslcontext,
server_side=server_side,
ssl_handshake_timeout=5, # arbitrarily small timeout so the test fails faster
)
reader._transport = new_transport
writer._transport = new_transport
async def server_cb(reader, writer):
# Sleeping 1 second seems to reliably reproduce the error
await asyncio.sleep(1)
sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
sslcontext.load_cert_chain(CERT_FILE, KEY_FILE)
await start_tls(reader, writer, sslcontext, server_side=True)
# We never get here
print(await reader.read(4))
writer.write(b"pong")
await writer.drain()
async def client(reader, writer):
sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
sslcontext.check_hostname = False
sslcontext.verify_mode = ssl.VerifyMode.CERT_NONE
await start_tls(reader, writer, sslcontext, server_side=False)
# We never get here
writer.write(b"ping")
await writer.drain()
print(await reader.read(4))
async def main():
with open(CERT_FILE, "w") as fp:
fp.write(CERT)
with open(KEY_FILE, "w") as fp:
fp.write(KEY)
server = await asyncio.start_server(
client_connected_cb=server_cb,
host="localhost",
port=0, # Let the OS pick an available port
)
task = asyncio.create_task(server.serve_forever())
try:
port = server.sockets[0].getsockname()[1]
reader, writer = await asyncio.open_connection(host="localhost", port=port)
await client(reader, writer)
writer.close()
await writer.wait_closed()
finally:
task.cancel()
asyncio.run(main())
The output:
Task exception was never retrieved
future: <Task finished name='Task-5' coro=<server_cb() done, defined at /Users/barak_alon/Library/Application Support/JetBrains/PyCharmCE2022.2/scratches/tls_race_condition.py:82> exception=ConnectionResetError()>
Traceback (most recent call last):
File "/Users/barak_alon/Library/Application Support/JetBrains/PyCharmCE2022.2/scratches/tls_race_condition.py", line 88, in server_cb
await start_tls(reader, writer, sslcontext, server_side=True)
File "/Users/barak_alon/Library/Application Support/JetBrains/PyCharmCE2022.2/scratches/tls_race_condition.py", line 71, in start_tls
new_transport = await loop.start_tls(
File "/Users/barak_alon/.pyenv/versions/3.9.7/lib/python3.9/asyncio/base_events.py", line 1231, in start_tls
await waiter
ConnectionResetError
Traceback (most recent call last):
File "/Users/barak_alon/Library/Application Support/JetBrains/PyCharmCE2022.2/scratches/tls_race_condition.py", line 129, in <module>
asyncio.run(main())
File "/Users/barak_alon/.pyenv/versions/3.9.7/lib/python3.9/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/Users/barak_alon/.pyenv/versions/3.9.7/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
return future.result()
File "/Users/barak_alon/Library/Application Support/JetBrains/PyCharmCE2022.2/scratches/tls_race_condition.py", line 123, in main
await client(reader, writer)
File "/Users/barak_alon/Library/Application Support/JetBrains/PyCharmCE2022.2/scratches/tls_race_condition.py", line 100, in client
await start_tls(reader, writer, sslcontext, server_side=False)
File "/Users/barak_alon/Library/Application Support/JetBrains/PyCharmCE2022.2/scratches/tls_race_condition.py", line 71, in start_tls
new_transport = await loop.start_tls(
File "/Users/barak_alon/.pyenv/versions/3.9.7/lib/python3.9/asyncio/base_events.py", line 1231, in start_tls
await waiter
ConnectionAbortedError: SSL handshake is taking longer than 5 seconds: aborting the connection
Anyone have any idea what's going on here? Is there a fix that doesn't require a custom asyncio Protocol?
Calling .pause_reading() on the transport before you try to elevate it to TLS might help.
I'm developing a Discord bot in Python 3 and can't get it running properly. I'm hosting the bot on a 1&1 server, booting it with nohup python3 main.py &. The bot is running and working perfectly for a while then crash with every times a huge Traceback of errors ending with RuntimeError: can't start new thread.. And furthermore the source line of the error from my code isn't the same each time. It always comes from an await [...] line.
I've been searching for a while on internet but other developers using import threading and related functions while I don't, i'm only using the async / await keywords. Is this a mistake ? I'm certain that i don't reach the thread limit, i've been testing my bot with only a few friends, so a maximum of 3 to 4 requests at a time. The bot is using asynchronous methods only for sending messages or reactions on Discord, there is no recursion anywhere.
Here is one of the multiple Traceback i've had. Hope somebody can help me, thanks !
`
Ignoring exception in on_message
Traceback (most recent call last):
File "/kunden/homepages/44/d758963141/htdocs/.local/lib/python3.7/site-packages/discord/client.py", line 333, in _run_event
await coro(*args, **kwargs)
File "main.py", line 261, in on_message
await message.channel.send(lines + "```")
File "/kunden/homepages/44/d758963141/htdocs/.local/lib/python3.7/site-packages/discord/abc.py", line 905, in send
nonce=nonce, allowed_mentions=allowed_mentions)
File "/kunden/homepages/44/d758963141/htdocs/.local/lib/python3.7/site-packages/discord/http.py", line 185, in request async with self.__session.request(method, url, **kwargs) as r:
File "/kunden/homepages/44/d758963141/htdocs/.local/lib/python3.7/site-packages/aiohttp/client.py", line 1012, in __aenter__
self._resp = await self._coro
File "/kunden/homepages/44/d758963141/htdocs/.local/lib/python3.7/site-packages/aiohttp/client.py", line 483, in _request
timeout=real_timeout
File "/kunden/homepages/44/d758963141/htdocs/.local/lib/python3.7/site-packages/aiohttp/connector.py", line 523, in connect
proto = await self._create_connection(req, traces, timeout)
File "/kunden/homepages/44/d758963141/htdocs/.local/lib/python3.7/site-packages/aiohttp/connector.py", line 859, in _create_connection
req, traces, timeout)
File "/kunden/homepages/44/d758963141/htdocs/.local/lib/python3.7/site-packages/aiohttp/connector.py", line 967, in _create_direct_connection
traces=traces), loop=self._loop)
File "/kunden/homepages/44/d758963141/htdocs/.local/lib/python3.7/site-packages/aiohttp/connector.py", line 830, in _resolve_host
self._resolver.resolve(host, port, family=self._family)
File "/kunden/homepages/44/d758963141/htdocs/.local/lib/python3.7/site-packages/aiohttp/resolver.py", line 30, in resolve
host, port, type=socket.SOCK_STREAM, family=family)
File "/usr/lib/python3.7/asyncio/base_events.py", line 789, in getaddrinfo
None, getaddr_func, host, port, family, type, proto, flags)
File "/usr/lib/python3.7/asyncio/base_events.py", line 752, in run_in_executor
executor.submit(func, *args), loop=self)
File "/usr/lib/python3.7/concurrent/futures/thread.py", line 160, in submit
self._adjust_thread_count()
File "/usr/lib/python3.7/concurrent/futures/thread.py", line 181, in _adjust_thread_count
t.start()
File "/usr/lib/python3.7/threading.py", line 847, in start
_start_new_thread(self._bootstrap, ())
RuntimeError: can't start new thread
`
===== EDIT =====
Here is a sample of my code :
`
#client.event
async def on_message(message) :
global messagesId
# ===== Block self messages =====
if message.author == client.user :
return
# ===== $register =====
elif message.content == "$register" :
if not(await isRegistered(message.author.id, message.channel)) :
try :
refreshDb()
sql = "INSERT INTO player VALUES (%s, %s, 0)"
dbCurs.execute(sql, (message.author.id, message.author.name))
sql = "INSERT INTO schedule(player_id) VALUES (%s)"
dbCurs.execute(sql, (message.author.id))
db.commit()
except Exception as e :
await message.channel.send("Erreur interne #9")
raise e
await message.channel.send("Tu as été enregistré.")
else :
await message.channel.send("Tu es déjà enregistré.")
# ===== $schedule =====
elif message.content == "$schedule" :
# Get player's current schedule
data = None
try :
if await isRegistered(message.author.id, message.channel) :
try :
refreshDb()
sql = "SELECT * FROM schedule WHERE player_id = %s"
dbCurs.execute(sql, (message.author.id))
data = dbCurs.fetchall()[0]
except Exception as e :
await message.channel.send("Erreur interne #4")
raise e
else :
await message.channel.send("Tu dois t'enregistrer pour utiliser cette commande.")
return
except Exception as e :
await message.channel.send("Erreur interne #5")
raise e
# Create lines
text = "<#{}>\n{}".format(message.author.id, getScheduleText(data, 1))
sentMessage = await message.channel.send(text)
# register message's id
messagesId[sentMessage.id] = message.author.id
# Add reactions
i = 0
keys = list(cols.keys())
for key in keys :
await sentMessage.add_reaction(bytes.decode(numbers[i]))
i += 1
# Register every messages id and delete everyone after 60 sec
await deleteSched(sentMessage)
`
Your code apparently is using threads, via a thread-pool-executor; this is intended to run long-lasting tasks but leave the main asyncio thread available to handle more events. Creating new threads in the executor will always happen when your code hits some await condition, as this is the only time the event loop is free to work.
So..., it seems like the tasks you are running in the executor are not ending, and you are ending up with very many stale threads. Without seeing the code, I don't think we can say more.
How can I get the response for every iteration, like a live stream feed?
Here is the RestAPI main.py:
from fastapi import FastAPI
from fastapi import Request
from fastapi import WebSocket
import asyncio
app = FastAPI()
#app.get("/ws_res")
async def websoc(websocket: WebSocket):
await websocket.accept()
for i in range(100000):
i = "John"
await asyncio.sleep(0.01)
await websocket.send_json({"msg": i})
await websocket.close()
Now, I am trying to get the response from python code but I'm receiving an error that says Unsupported upgrade request.
Here is the output from API side :
INFO: Started server process [67680]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
WARNING: Unsupported upgrade request.
Here is the python code that I used to access the API (test.py):
import asyncio
import websockets
async def hello():
uri = "ws://127.0.0.1:8000/ws_res"
async with websockets.connect(uri) as websocket:
greeting = await websocket.recv()
print(f"< {greeting['msg']}")
asyncio.get_event_loop().run_until_complete(hello())
Traceback (most recent call last):
File "test.py", line 12, in <module>
asyncio.get_event_loop().run_until_complete(hello())
File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
return future.result()
File "test.py", line 7, in hello
async with websockets.connect(uri) as websocket:
File "/home/test/env/lib/python3.8/site-packages/websockets/client.py", line 517, in __aenter__
return await self
File "/home/test/env/lib/python3.8/site-packages/websockets/client.py", line 542, in __await_impl__
await protocol.handshake(
File "/home/test/env/lib/python3.8/site-packages/websockets/client.py", line 296, in handshake
raise InvalidStatusCode(status_code)
websockets.exceptions.InvalidStatusCode: server rejected WebSocket connection: HTTP 400
Fastapi websocket endpoints need to be defined using the websocket decorator, not the get decorator:
#app.websocket("/ws_res")
async def websoc(websocket: WebSocket):
await websocket.accept()
for i in range(100000):
i = "John"
await asyncio.sleep(0.01)
await websocket.send_json({"msg": i})
await websocket.close()
See the documentation for full details: https://fastapi.tiangolo.com/advanced/websockets/
I'm using aiohttp as server and telethon client for sending messages.
Running this edited code from telegrammodule.py is working fine:
from telethon import TelegramClient
import asyncio
api_id = censored
api_hash = "censored"
client = TelegramClient('anon', api_id, api_hash)
async def sendMessageToUser(user, message):
await client.send_message(user, message)
def sendMessage(user, message):
with client:
client.loop.run_until_complete(sendMessageToUser(user, message))
sendMessage("censored", "Hello")
This is the error I get when I try to call the function sendMessage() from server.py:
======== Running on http://0.0.0.0:5000 ========
(Press CTRL+C to quit)
Error handling request
Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/aiohttp/web_protocol.py", line 418, in start
resp = await task
File "/usr/local/lib/python3.7/dist-packages/aiohttp/web_app.py", line 458, in _handle
resp = await handler(request)
File "server.py", line 9, in send
response = await sendMessage(user, message)
File "/home/user/telegram_user_bot/telegrammodule.py", line 13, in sendMessage
client.loop.run_until_complete(sendMessageToUser(user, message))
File "/usr/lib/python3.7/asyncio/base_events.py", line 571, in run_until_complete
self.run_forever()
File "/usr/lib/python3.7/asyncio/base_events.py", line 526, in run_forever
raise RuntimeError('This event loop is already running')
RuntimeError: This event loop is already running
Task exception was never retrieved
future: <Task finished coro=<sendMessageToUser() done, defined at /home/user/telegram_user_bot/telegrammodule.py:8> exception=ConnectionError('Cannot send requests while disconnected')>
Traceback (most recent call last):
File "/home/user/telegram_user_bot/telegrammodule.py", line 9, in sendMessageToUser
await client.send_message(user, message)
File "/usr/local/lib/python3.7/dist-packages/telethon/client/messages.py", line 752, in send_message
result = await self(request)
File "/usr/local/lib/python3.7/dist-packages/telethon/client/users.py", line 53, in __call__
future = self._sender.send(request, ordered=ordered)
File "/usr/local/lib/python3.7/dist-packages/telethon/network/mtprotosender.py", line 170, in send
raise ConnectionError('Cannot send requests while disconnected')
ConnectionError: Cannot send requests while disconnected
Here's the code from server.py:
from telegrammodule import sendMessage
from aiohttp import web
import asyncio
async def send(request):
data = await request.post()
user = data['user']
message = data['message']
response = await sendMessage(user, message)
app = web.Application()
app.router.add_post("/send", send)
if __name__ == "__main__":
web.run_app(app, port=5000)
And here from telegrammodule.py:
from telethon import TelegramClient
import asyncio
api_id = censored
api_hash = "censored"
client = TelegramClient('anon', api_id, api_hash)
async def sendMessageToUser(user, message):
await client.send_message(user, message)
async def sendMessage(user, message):
async with client:
client.loop.run_until_complete(sendMessageToUser(user, message))
I don't know how to solve the problem. How can I fix it?
If a loop is already running, you can't start it one more time. Use create_task, to add a task to a running loop.
For your case
client.loop.create_task(sendMessageToUser(user, message))
would be a fix, I guess.
Also, if the client.loop is in another thread, you might use run_coroutine_threadsafe:
asyncio.run_coroutine_threadsafe(sendMessageToUser(user, message), client.loop)
And one more important thing - if client.loop is the loop you're currently in, you can await sendMessageToUser(user, message) until message is sent.
I'm learning thenextquant quant framework, but always get connection error while connecting to RabbitMQ. after some troubleshooting, i found asynico/aioamqp module always prompts error:An open stream was garbage collected prior to establishing network connection; call "stream.close()" explicitly.
while trying to connect to RabbitMQ server, RabbitMQ is up and running and other client can connect to it without any error.
Then I followed the hello world example from aioamqp(https://github.com/Polyconseil/aioamqp/blob/master/examples/send.py) to write a test program, then reproduced the error.
import asyncio
import aioamqp
async def send():
transport, protocol = await aioamqp.connect(host="127.0.0.1", port=5672, login="guest", password="guest", login_method="PLAIN")
channel = await protocol.channel()
await channel.queue_declare(queue_name='hello')
await channel.basic_publish(
payload='Hello World!',
exchange_name='',
routing_key='hello'
)
print(" [x] Sent 'Hello World!'")
await protocol.close()
transport.close()
asyncio.get_event_loop().run_until_complete(send())
(venv_380) appledeMBP:Market apple$ python hello.py
An open stream was garbage collected prior to establishing network connection; call "stream.close()" explicitly.
Traceback (most recent call last):
File "hello.py", line 31, in <module>
asyncio.get_event_loop().run_until_complete(send())
File "/Users/apple/.pyenv/versions/3.8.0/lib/python3.8/asyncio/base_events.py", line 608, in run_until_complete
return future.result()
File "hello.py", line 14, in send
transport, protocol = await aioamqp.connect(host="127.0.0.1", port=5672, login="guest", password="guest", login_method="PLAIN")
File "/Users/apple/.virtualenvs/venv_380/lib/python3.8/site-packages/aioamqp/__init__.py", line 59, in connect
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
File "/Users/apple/.pyenv/versions/3.8.0/lib/python3.8/asyncio/trsock.py", line 82, in setsockopt
self._sock.setsockopt(*args, **kwargs)
OSError: [Errno 9] Bad file descriptor
finally I found it's caused by version of Python. the issue is gone once using 3.6 instead of 3.8 which result in connection issue with aioamqp.connect()