so I want to establish connection with the server initially then send the data from some other function depending upon the choice of user how do i get this done??
import websockets
import asyncio
async def connect():
#i need some code here to connect to 'ws://127.0.0.1:8000'
async def send_data1(websocket):
...#some code here
await websocket.send(data)
async def send_data2(websocket):
...#some code here
await websocket.send(data)
def main():
name=input()
if name=='xyz':
send_data1()
else:
send_data2()
Related
I hope websockets can running in background.
Once received the message, print it.
Other function can call it's 'send' function to send message
But the code under 'loop.run_until_complete(Iao())' will no running.
I tried use 'threading' then put websockets in other thread, it's still can't running.
Is it possible to achieve it? except create a async function
import asyncio
import websockets
import time
class WebsocketHandler():
def __init__(self):
self.conn = None
async def connect(self, url):
self.conn = await websockets.connect(url)
async def send(self, msg):
await self.conn.send(msg)
async def receive(self):
while True:
print(await self.conn.recv())
async def close(self):
await self.conn.close()
async def Iao():
global handler
handler = WebsocketHandler()
await handler.connect('ws://localhost:8765')
await handler.receive()
await handler.send('{"action":"plus"}')
await handler.close()
loop = asyncio.get_event_loop()
loop.run_until_complete(Iao())
while True:
print("1")
asyncio.run(handler.send('{"action":"plus"}'))
print("2")
time.sleep(2)
I'm new to websockets and asyncio and I'm trying to get a simple example working. I would like to create a server that accepts connections from multiple clients and concurrently runs a loop that sends a message to every connection once a second. I'm also trying to use asyncio.run() which I believe is preferred to the get_event_loop() code on which many examples are based.
Here's my code so far:
import asyncio
import websockets
USERS = set()
async def register(websocket, path):
USERS.add(websocket)
await websocket.send("Successfully registered")
async def count():
count = 0
while True:
print(f"Iteration: {count}")
if USERS:
for user in USERS:
await user.send("Sending message back to client")
await asyncio.sleep(1)
count +=1
async def serve():
server = await websockets.serve(register, 'localhost', 8765)
await server.wait_closed()
print("Server closed")
async def main():
await asyncio.gather(count(), serve())
asyncio.run(main())
When I run this the count coroutine works until I make a connection from a client. At this point the connection is successfully registered but when I try to send a message back to the client in count() I get an error because the connection is already closed. How should I change my code to stop this from happening?
How should I change my code to stop this from happening?
The problem might be that your handler, the register coroutine, is returning immediately, which prompts websockets to close the connection. Try to change it like this:
async def register(websocket, path):
USERS.add(websocket)
await websocket.send("Successfully registered")
await asyncio.Event().wait()
If that helps, you can put the event in USERS along with websocket, so that you have a way to terminate the connection to the client when you want to.
I am trying to messing up with Websockets module and after checking the main page:
https://websockets.readthedocs.io/en/stable/intro.html
I did following:
SERVER
# SERVER
import asyncio
import websockets
import nest_asyncio
USERS = {}
async def set_online(websocket, user_name):
USERS[user_name] = websocket
await notify()
async def set_offline(websocket, user_name):
USERS.pop(user_name, None)
await notify()
async def notify():
if USERS:
message = "Online users: {}\n".format(len(USERS))
print (message)
#await asyncio.wait([user.send(message) for user in USERS])
else:
message = "Online users: 0\n"
print (message)
async def server(websocket, path):
user_name = await websocket.recv()
await set_online(websocket, user_name)
try:
async for message in websocket:
for user_name, user_ws in USERS.items():
if websocket == user_ws:
print (f"{user_name}: {message}")
finally:
await set_offline(websocket, user_name)
start_server = websockets.serve(server, "localhost", 3000,
ping_interval=None)
nest_asyncio.apply()
loop = asyncio.get_event_loop()
loop.run_until_complete(start_server)
loop.run_forever()
and also:
CLIENT
# CLIENT
import asyncio
import websockets
import nest_asyncio
async def client(localhost, port):
uri = "ws://{0}:{1}".format(localhost, str(port))
async with websockets.connect(uri) as websocket:
user_name = input("set your name: ")
await websocket.send(f"{user_name}")
while True:
message = input("> ")
if message == "/quit":
break
else:
await websocket.send(message)
host = "localhost"
port = 3000
nest_asyncio.apply()
loop = asyncio.get_event_loop()
loop.run_until_complete(client(host, port))
so all works as expected but I would like to achieve that each user can receive the answer as well from other users.
I found there is a conflict when I want to use websocket.send(message) in for loop async for message in websocket: on SERVER side
The link which I paste above, I think has a solution but I am struggling to figure out how to use it properly in my script.
I believe I need to create two tasks (send and recv) which will work in parallel.
Like:
async def handler(websocket, path):
consumer_task = asyncio.ensure_future(consumer_handler(websocket, path))
producer_task = asyncio.ensure_future(producer_handler(websocket, path))
done, pending = await asyncio.wait([consumer_task, producer_task],return_when=asyncio.FIRST_COMPLETED)
for task in pending:
task.cancel()
the following is displayed on the website which I provided above, just one thing needs to be changed from asyncio.ensure_future to asyncio.create_task. I implemented function handler, producer, consumer, producer_handler and consumer_handler to make it works but no luck.
Could someone provide an example or how this should be set up correctly?
I believe asyncio.create_task should be used on both (SERVER and CLIENT) so they both receive and send at one time.
This is pretty long but I hope someone can help me with it and also maybe my part of script will be handy for someone as well!
I want to send values from a for loop from the client-server but the server only receives the first value and the connection is cut shortly
Client
import asyncio
import websockets
import time
async def message():
async with websockets.connect("ws://-------:5051") as socket:
for i in range(20):
await socket.send(f"{i}")
print(i)
time.sleep(4)
asyncio.get_event_loop().run_until_complete(message())
Server
import asyncio
import websockets
async def consumer_handler(websocket,path):
client_type = await websocket.recv()
print(client_type)
start_server = websockets.serve(consumer_handler,"ws://-------:5051", 5051)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
So, your consumer_handler receives message once and finishes.
You need to add loop.
Try something like this:
async def consumer_handler(websocket, path):
async for msg in websocket:
print(msg)
In Python, I'm using "websockets" library for websocket client.
import asyncio
import websockets
async def init_sma_ws():
uri = "wss://echo.websocket.org/"
async with websockets.connect(uri) as websocket:
name = input("What's your name? ")
await websocket.send('name')
greeting = await websocket.recv()
The problem is the client websocket connection is disconnected once a response is received. I want the connection to remain open so that I can send and receive messages later.
What changes do I need to keep the websocket open and be able to send and receive messages later?
I think your websocket is disconnected due to exit from context manager after recv().
Such code works perfectly:
import asyncio
import websockets
async def init_sma_ws():
uri = "wss://echo.websocket.org/"
async with websockets.connect(uri) as websocket:
while True:
name = input("What's your name? ")
if name == 'exit':
break
await websocket.send(name)
print('Response:', await websocket.recv())
asyncio.run(init_sma_ws())
In your approach you used a asynchronous context manager which closes a connection when code in the block is executed. In the example below an infinite asynchronous iterator is used which keeps the connection open.
import asyncio
import websockets
async def main():
async for websocket in websockets.connect(...):
try:
...
except websockets.ConnectionClosed:
continue
asyncio.run(main())
More info in library's docs.