High-performanceWebSocketsforyourFlaskappspoweredbyuWSGI.Low-leveluWSGIWebSocketAPIaccessandflexiblehigh-levelabstractionsforbuildingcomplexWebSocketapplicationswithFlask.SupportsseveraldifferentconcurrencymodelsincludingGevent.InspiredbyFlask-Sockets.
fromflaskimportFlaskfromflask_uwsgi_websocketimportGeventWebSocketapp=Flask(__name__)websocket=GeventWebSocket(app)@websocket.route('/echo')defecho(ws):whileTrue:msg=ws.receive()ws.send(msg)if__name__=='__main__':app.run(gevent=100)InstallationPreferredmethodofinstallationisviapip:
$pipinstallFlask-uWSGI-WebSocketInstallinguWSGIOfcourseyou'llalsoneeduWSGI(withSSLsupport,atminimum).Itcanalsobeinstalledwithpip:
$pipinstalluwsgiIfthatfailsoryouneedtoenabletheasyncioplugin,readon.
uWSGIonMacOSXOnsomeversionsofMacOSX,OpenSSLheadersarenolongerincluded.IfyouuseHomebrew,installOpenSSLandensuretheyareavailable:
$brewinstallopenssl&&brewlinkopenssl--forceThisshouldensurepipcaninstalluWSGI:
$LDFLAGS="-L/usr/local/lib"pipinstalluwsgi--no-use-wheelIfyouplantousetheasyncioplugin,you'llneedtoensurethatit'senabledwhenuWSGIiscompiled.YoucanuseUWSGI_PROFILEtodothis.WithHomebrewPython3.5installed:
$LDFLAGS="-L/usr/local/lib"CFLAGS="-I/usr/local/include/python3.5m"UWSGI_PROFLILE="asyncio"pip3installuwsgi--no-use-wheeluWSGIonLinuxIfyourLinuxdistributionincludesuWSGIwithspecificplugins,thatismanytimesyourbestbet.Ifthatfailsoryou'dprefertocompileuWSGIyourself,you'llneedtoensurethattherequisitebuildtools,OpenSSLheaders,etcareinstalled:
$apt-getinstallbuild-essentiallibssl-devpython3-devpython3-venvAccordingtotheuWSGIasynciodocs,UWSGI_PROFILEandgreenlet.hlocationshouldbespecified.
IfyouareinstallinguWSGIintoavirtualenv,theprocessis:
$python3-mvenvpyvenv$.pyvenv/bin/activate(pyvenv)$pipinstallgreenletNow,greenlet.hshouldbeavailableat$VIRTUAL_ENV/include/site/python3.5.Tobuildwithpip:
$mkdir-p$VIRTUAL_ENV/include/site/python3.5/greenlet$ln-s../greenlet.h$VIRTUAL_ENV/include/site/python3.5/greenlet/$CFLAGS="-I$VIRTUAL_ENV/include/site/python3.5"UWSGI_PROFILE="asyncio"pipinstalluwsgi--no-use-wheelDeploymentYoucanuseuWSGI'sbuilt-inHTTProutertogetupandrunningquickly:
$uwsgi--master--http:8080--http-websockets--wsgiecho:app...whichiswhatapp.rundoesafterwrappingyourFlaskapp:
app.run(debug=True,host='localhost',port=8080,master=true,processes=8)uWSGIsupportsseveralconcurrencymodels,inparticularithasnicesupportforGevent.IfyouwanttouseGevent,importflask_uwsgi_websocket.GeventWebSocketandconfigureuWSGItousethegeventloopengine:
$uwsgi--master--http:8080--http-websockets--gevent100--wsgiecho:app...or:
app.run(debug=True,gevent=100)Notethatyoucannotusemultiplethreadswithgeventloopengine.
Toenableasyncioinstead:
$uwsgi--master--http:5000--http-websockets--asyncio100--greenlet--wsgichat:app...or:
app.run(debug=True,asyncio=100,greenlet=True)Forproductionyou'llprobablywanttorunuWSGIbehindHaproxyorNginx,insteadofusingthebuilt-intHTTProuter.ExploretheuWSGIdocumentationtolearnmoreaboutthevariousconcurrencyanddeploymentoptions.
DevelopmentIt'spossibletotakeadvantageofFlask'sinteractivedebuggerbyinstallingWerkzeug'sDebuggedApplicationmiddleware:
fromwerkzeug.debugimportDebuggedApplicationapp.wsgi_app=DebuggedApplication(app.wsgi_app,True)...andrunninguWSGIwithonlyasingleworker:
$uwsgi--master--http:8080--http-websockets--wsgi-file--workers1--threads8app.pyIfyouuseapp.run(debug=True)orexportFLASK_UWSGI_DEBUG,Flask-uWSGI-Websocketwilldothisautomaticallyforyou.
ExamplesThereareseveralexamplesavailablehere.
APIWebSocketAppliesWebSocketMiddlewaretoyourFlaskApp,allowingyoutodecoraterouteswiththeroutemethod,turningthemintoWebSockethandlers.
Additionallymonkey-patchesapp.run,torunyourappdirectlyinuWSGI.
route(url)
run(debug,host,port,**kwargs)**kwargsarepassedtouWSGIascommandlinearguments.
WebSocketMiddlewareWebSocketMiddlewarewhichautomaticallyperformsWebSockethandshakeandpassesWebSocketClientinstancestoyourroute.
WebSocketClientExposestheuWSGIWebSocketAPI.
recv()(aliasWebSocket.receive())
recv_nb()
send(msg)
send_binary(msg)
recv_nb()
send_from_sharedarea(id,pos)
send_binary_from_sharedarea(id,pos)
GeventWebSocketFancierWebSocketabstractionthattakesadvantageofGeventloopengine.RequiresuWSGItoberunwith--uwsgioption.
GeventWebSocketMiddlewareAutomaticallyperformsWebSockethandshakeandpassesaGeventWebSocketClientinstancetoyourroute.
GeventWebSocketClientWebSocketclientabstractionwithfullynon-blockingmethods.
receive()
send(msg)
close()
connected
AsyncioWebSocketFancierWebSocketabstractionthattakesadvantageofAsyncioloopengine.RequiresuWSGItoberunwith--asyncioand--greenletoption.
AsyncioWebSocketMiddlewareAutomaticallyperformsWebSockethandshakeandpassesaAsyncioWebSocketClientinstancetoyourroute.
AsyncioWebSocketClientWebSocketclientabstractionwithasynciocoroutines.
coroutinea_recv()(aliasreceive(),recv())
coroutinea_send(msg)(aliassend())
recv_nb()(shouldbeuseless)
send_nb()(shouldbeuseless)
close()
connected
AdvancedUsageNormallywebsocketrouteshappenoutsideofthenormalrequestcontext.Youcangetarequestcontextinyourwebsockethandlerbyusingapp.request_context:
app=Flask(__name__)ws=GeventWebSocket(app)@ws.route('/websocket')defwebsocket(ws):withapp.request_context(ws.environ):printrequest.args
评论