WebSocket-for-Python (ws4py)
ws4py is a WebSocket client and server library for Python, supporting Python 3.6+ since version 0.6.0. It provides a straightforward API for building WebSocket applications, offering both threaded and eventlet/gevent-based server implementations. The library is currently in maintenance mode, with its last release (0.6.0) in 2021.
Common errors
-
ImportError: No module named 'gevent'
cause Attempting to use `ws4py.server.geventserver.WebSocketServer` or `geventserver.WSGIWebSocketServer` without `gevent` installed.fixInstall the `gevent` package: `pip install gevent`. -
TypeError: __init__() missing 1 required positional argument: 'sock'
cause This error often occurs when you try to instantiate a `WebSocket` subclass directly without passing the socket object, which is usually handled by the server wrapper (e.g., `WebSocketWSGIRequestHandler`).fixEnsure your `WebSocket` subclass is instantiated by the `WebSocketWSGIRequestHandler` or similar server component, not directly. If you're building a client, use `WebSocketClient`. -
WebSocket connection to 'ws://localhost:8000/' failed: Error during WebSocket handshake: Unexpected response code: 404
cause The client attempted to connect to a WebSocket URL that either doesn't exist, is incorrect, or where no WebSocket server is running or properly configured to handle WebSocket requests.fixVerify the WebSocket server is running and listening on the correct host and port, and that the URL path (`/` in this example) is correctly mapped to a WebSocket handler on the server side.
Warnings
- breaking Version 0.6.0 dropped official support for Python versions older than 3.6. Code relying on Python 2.x or 3.0-3.5 will break.
- gotcha Using `ws4py.server.geventserver` or `ws4py.server.eventletserver` requires the respective `gevent` or `eventlet` library to be installed separately. An `ImportError` will occur if they are missing.
- gotcha The library's development is slow, with the last release in 2021. It might not include the latest WebSocket protocol extensions or offer modern asyncio-based concurrency patterns.
Install
-
pip install ws4py
Imports
- WebSocketClient
from ws4py import WebSocketClient
from ws4py.client.threadedclient import WebSocketClient
- WebSocket
from ws4py.server import WebSocket
from ws4py.websocket import WebSocket
- WebSocketServer
from ws4py.server.wsgirefserver import WebSocketWSGIRequestHandler, WSGIServer
Quickstart
import time
from ws4py.client.threadedclient import WebSocketClient
class DummyClient(WebSocketClient):
def opened(self):
print("WebSocket opened. Sending messages...")
for i in range(0, 5):
self.send('Hello %d' % i)
time.sleep(0.5)
self.send('Bye')
def closed(self, code, reason=None):
print("WebSocket closed: %d %s" % (code, reason))
def received_message(self, m):
print("Received: %s" % m)
if m.data == b'Bye':
self.close()
# Note: This client expects a WebSocket server to be running at ws://localhost:9000/
# For a full runnable example, you'd also need a server like:
# from ws4py.server.wsgirefserver import WSGIServer, WebSocketWSGIRequestHandler
# from ws4py.websocket import WebSocket
# from threading import Thread
# class EchoWebSocket(WebSocket):
# def received_message(self, message):
# self.send(message.data, message.is_binary)
# server = WSGIServer(('localhost', 9000), WebSocketWSGIRequestHandler, websocket_class=EchoWebSocket)
# Thread(target=server.serve_forever).start()
if __name__ == '__main__':
try:
ws = DummyClient('ws://localhost:9000/', protocols=['http-only', 'chat'])
ws.connect()
ws.run_forever()
except KeyboardInterrupt:
ws.close()