Python websockets connecting through the internet using IPV6 - python

I want to send messages between two PCs accessing the internet through different networks. I have already created a firewall rule for the port in the server PC. The code works when both of them are using the same WiFi but not when using different connections.
Server (PC #1)
import asyncio
import websockets
import socket
async def hello(websocket):
name = await websocket.recv()
print(f"<<< {name}")
greeting = f"Hello {name}!"
await websocket.send(greeting)
print(f">>> {greeting}")
async def main():
async with websockets.serve(hello, "", port=8765):
await asyncio.Future() # run forever
if __name__ == "__main__":
asyncio.run(main())
Client (PC #2)
import asyncio
import websockets
import socket
async def hello():
uri = "ws://[2a02:8388:8bc7:4d00:1921:8126:966d:8d32]:8765"
#not my real IP
async with websockets.connect(uri) as websocket:
name = input("What's your name? ")
await websocket.send(name)
print(f">>> {name}")
greeting = await websocket.recv()
print(f"<<< {greeting}")
if __name__ == "__main__":
asyncio.run(hello())

Related

I need help to connection websocket in python3

I try connect to websocket but i have error:
server rejected WebSocket connection: HTTP 403
but when i try in website it's run like this website:
http://www.epetool.com/websocket/
the code in python 3.9:
import asyncio
import websockets
async def handler(websocket):
while True:
message = await websocket.recv()
print(message)
async def main():
url = "wss://io.dexscreener.com/dex/screener/pairs/h6/1?rankBy[key]=volume&rankBy[order]=desc&filters[buys][h1][min]=100&filters[sells][h1][min]=100&filters[liquidity][min]=500&filters[pairAge][max]=1&filters[chainIds][0]=bsc"
async with websockets.connect(url) as ws:
await handler(ws)
await asyncio.Future() # run forever
if __name__ == "__main__":
asyncio.run(main())

Websocket getting closed immediately after connecting to FastAPI Endpoint

I'm trying to connect a websocket aiohttp client to a fastapi websocket endpoint, but I can't send or recieve any data because it seems that the websocket gets closed immediately after connecting to the endpoint.
server
import uvicorn
from fastapi import FastAPI, WebSocket
app = FastAPI()
#app.websocket('/ws')
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
...
if __name__ == '__main__':
uvicorn.run('test:app', debug=True, reload=True)
client
import aiohttp
import asyncio
async def main():
s = aiohttp.ClientSession()
ws = await s.ws_connect('ws://localhost:8000/ws')
while True:
...
asyncio.run(main())
When I try to send data from the server to the client when a connection is made
server
#app.websocket('/ws')
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
await websocket.send_text('yo')
client
while True:
print(await ws.receive())
I always get printed in my client's console
WSMessage(type=<WSMsgType.CLOSED: 257>, data=None, extra=None)
While in the server's debug console it says
INFO: ('127.0.0.1', 59792) - "WebSocket /ws" [accepted]
INFO: connection open
INFO: connection closed
When I try to send data from the client to the server
server
#app.websocket('/ws')
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
await websocket.receive_text()
client
ws = await s.ws_connect('ws://localhost:8000/ws')
await ws.send_str('client!')
Nothing happens, I get no message printed out in the server's console, just the debug message saying the client got accepted, connection opened and closed again.
I have no idea what I'm doing wrong, I followed this tutorial in the fastAPI docs for a websocket and the example there with the js websocket works completely fine.
The connection is closed by either end (client or server), as shown from your code snippets. You would need to have a loop in both the server and the client for being able to await for messages, as well as send messages, continuously (have a look here and here).
Additionally, as per FastAPI's documentation:
When a WebSocket connection is closed, the await websocket.receive_text() will raise a WebSocketDisconnect
exception, which you can then catch and handle like in this example.
Thus, on server side, you should use a try-except block to catch and handle WebSocketDisconnect exceptions. Below is a working example demonstrating a client (in aiohttp) - server (in FastAPI) communication using websockets.
Working Example
Server
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
import uvicorn
app = FastAPI()
#app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
# await for connections
await websocket.accept()
try:
# send "Connection established" message to client
await websocket.send_text("Connection established!")
# await for messages and send messages
while True:
msg = await websocket.receive_text()
if msg.lower() == "close":
await websocket.close()
break
else:
print(f'CLIENT says - {msg}')
await websocket.send_text(f"Your message was: {msg}")
except WebSocketDisconnect:
print("Client disconnected")
if __name__ == "__main__":
uvicorn.run(app, host="127.0.0.1", port=8000)
Client
import aiohttp
import asyncio
async def main():
async with aiohttp.ClientSession() as session:
async with session.ws_connect('ws://127.0.0.1:8000/ws') as ws:
# await for messages and send messages
async for msg in ws:
if msg.type == aiohttp.WSMsgType.TEXT:
print(f'SERVER says - {msg.data}')
text = input('Enter a message: ')
await ws.send_str(text)
elif msg.type == aiohttp.WSMsgType.ERROR:
break
asyncio.run(main())

Python Websockets: Why can't the client connect to my server

I'm using the websockets Python library.
So I have a client which simply is
# client.py
import websockets
import asyncio
async def main():
print("SENDING")
async with websockets.connect(f"ws://{IP}:8765") as connection:
await connection.send("Poggers")
print("END")
if __name__ == "__main__":
asyncio.run(main())
where IP is the IPv4 address I get when I visit https://whatismyipaddress.com.
My server code is
# server.py
import asyncio
import websockets
async def handle_server(websocket, path):
async for message in websocket:
print(message)
async def main():
async with websockets.serve(handle_server, "0.0.0.0", 8765):
await asyncio.Future()
if __name__ == "__main__":
asyncio.run(main())
Say I'm running the server code (server.py) and my friend's running the client code (client.py), in that order. For some reason, all he sees on his screen is
SENDING
and it hangs.
I see nothing on my screen.
Why is that?

How to implement recv and send at one time correctly

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!

Python Websocket only receives once from client

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)

Categories