I'm trying to receive websocket messages in a greenlet, but it doent seem to be working. I have this code:
import gevent
from geventwebsocket.handler import WebSocketHandler
from gevent.pywsgi import WSGIServer
from geventwebsocket import WebSocketServer, WebSocketApplication, Resource
def recvWs(ws):
gevent.sleep(0)
recvedData = ws.receive()
rData = json.loads(recvedData)
print(rData)
def app(environ, start_response):
websocket = environ['wsgi.websocket']
while True:
gevent.spawn(recvWs,websocket)
gevent.sleep(0)
if __name__ == '__main__':
server = WSGIServer(("0.0.0.0", 80), app,handler_class=WebSocketHandler)
server.serve_forever()
And when running, it returns this error:
<Greenlet "Greenlet-0" at 0x23fa4306148:
recvWs(<geventwebsocket.websocket.WebSocket object at 0x0)> failed with
RuntimeError
As well as:
line 197, in read_frame
header = Header.decode_header(self.stream)
How do I fix this?
Here is an example of what I have done that works very well.
Python with bottle and gevent:
from gevent import sleep as gsleep, Timeout
from geventwebsocket import WebSocketError
from bottle import Bottle, get, post, route, request, response, template, redirect, abort
@route('/ws/app')
def handle_websocket():
wsock = request.environ.get('wsgi.websocket')
if not wsock:
abort(400, 'Expected WebSocket request.')
# Send initial data here
wsock.send(json.dumps(data))
while 1:
try:
#Process incoming message. 2 second timeout to not block
message = {}
with Timeout(2, False) as timeout:
message = wsock.receive()
if message:
message = json.loads(message)
if isinstance(message, dict):
# Do something with data and return
wsock.send(json.dumps(result))
# Add an additional second just for sanity. Not necessarily needed
gsleep(1)
except WebSocketError:
break
except Exception as exc:
traceback.print_exc()
gsleep(2)
Then in your javascript you open a websocket connection and send and recieve the data as you would normally.