Botella+WebSocket
bottle (2)
Probablemente esta no sea la respuesta más fácil, pero acabo de configurar un entorno de prueba que funciona usando Nginx y uWSGI sobre Pyramid y una vez que lo tienes configurado puedes extenderlo muy fácilmente, por ejemplo si tu / ws es tirando demasiados recursos, es trivial con Nginx + uWSGI trasladar / ws a diferentes hardware. Mi formación es Pyramid y mi experiencia en uWSGI solo ha sido con las pruebas, pero en mi lectura parece una solución que debería funcionar bien. Las instrucciones de la botella fueron el resultado de una búsqueda rápida en Google.
El concepto:
El concepto es llevar tu aplicación, es decir, tu aplicación = make_wsgi_app.from_config (config) antes de la llamada app.serve_forever () y en su lugar usar uwsgi para ''servir'' tu aplicación a un socket app1.sock . Hay muchas formas de configurar uWSGI. El sitio de uWSGI tiene documentación para más formas de configurar uWSGI para hablar con su aplicación. Nginx viene con la configuración para usar sockets uWSGI de forma nativa al menos en la versión actual. Acaba de pasar el uwsgi_pass unix: ///tmp/app1.sock; ruta de acceso a la configuración de los sitios junto con los parámetros. Haga esto dos veces en el mismo archivo de conf de sitio, una vez para la ubicación / { y una para la ubicación / ws { señalando sus respectivos archivos de la aplicación y debe estar listo para continuar.El concepto de servir una aplicación en un socket como archivo era nuevo para mí cuando estaba configurando el entorno de prueba, espero que esto ayude.
Que conseguir:
nginxuSSGI
Cómo:
Extraiga la información de configuración de nginx y uwsgi de este tutorial y bríndelo a su aplicación, aquí para la configuración específica de la botella o diríjase al sitio uwsgi y revise sus instrucciones de configuración. La documentación para cada tecnología específica es bastante buena, por lo que incluso con la falta de ejemplos combinados, no fue difícil hacer que trabajaran juntos. Con Nginx y uWSGI hay una gran cantidad de ajustes de configuración, así que asegúrese de echarles un vistazo también.¿es posible alojar una aplicación de botella normal y una de WebSocket (ejemplo: https://github.com/defnull/bottle/blob/master/docs/async.rst ) en la misma aplicación (mismo puerto)? Entonces, / ws irá al manejador WebSocket y el resto se enrutará normalmente a otros manejadores de botella.
Seguro que lo es.
El servidor:
#!/usr/bin/python
import json
from bottle import route, run, request, abort, Bottle ,static_file
from pymongo import Connection
from gevent import monkey; monkey.patch_all()
from time import sleep
app = Bottle()
@app.route(''/websocket'')
def handle_websocket():
wsock = request.environ.get(''wsgi.websocket'')
if not wsock:
abort(400, ''Expected WebSocket request.'')
while True:
try:
message = wsock.receive()
wsock.send("Your message was: %r" % message)
sleep(3)
wsock.send("Your message was: %r" % message)
except WebSocketError:
break
@app.route(''/<filename:path>'')
def send_html(filename):
return static_file(filename, root=''./static'', mimetype=''text/html'')
from gevent.pywsgi import WSGIServer
from geventwebsocket import WebSocketHandler, WebSocketError
host = "127.0.0.1"
port = 8080
server = WSGIServer((host, port), app,
handler_class=WebSocketHandler)
print "access @ http://%s:%s/websocket.html" % (host,port)
server.serve_forever()
La página html que contiene el javascript:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript">
var ws = new WebSocket("ws://localhost:8080/websocket");
ws.onopen = function() {
ws.send("Hello, world");
};
ws.onmessage = function (evt) {
alert(evt.data);
};
</script>
</head>
<body>
</body>
</html>
Un cliente:
#!/usr/bin/python
from websocket import create_connection
ws = create_connection("ws://localhost:8080/websocket")
print "Sending ''Hello, World''..."
ws.send("Hello, World")
print "Sent"
print "Reeiving..."
result = ws.recv()
print "Received ''%s''" % result
ws.close()