Skip to content

Commit

Permalink
merge flask app and websocket into the same twisted server
Browse files Browse the repository at this point in the history
  • Loading branch information
SamuelDudley committed Feb 26, 2017
1 parent 88a7bbd commit 72f1a9b
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 52 deletions.
70 changes: 34 additions & 36 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
Samuel Dudley
Jan 2016
'''

import os, json, time, sys, uuid, urllib2

from MAVProxy.modules.lib import mp_module
Expand All @@ -13,9 +12,15 @@
import threading, Queue

from autobahn.twisted.websocket import WebSocketServerProtocol, WebSocketServerFactory
from twisted.python import log
from autobahn.twisted.resource import WebSocketResource, WSGIRootResource
from twisted.web.server import Site
from twisted.web.wsgi import WSGIResource
from twisted.internet import reactor

from twisted.python import log

from app import cesium_web_server # the Flask webapp

import webbrowser # open url's in browser window

class ServerProtocol(WebSocketServerProtocol):
Expand Down Expand Up @@ -62,58 +67,52 @@ def __init__(self, mpstate):
self.flightmode = None

self.cesium_settings = mp_settings.MPSettings(
[ ('localwebserver', bool, True),
('openbrowser', bool, True),
('debug', bool, False)])
[ ('openbrowser', bool, False),
('debug', bool, True)])

self.aircraft = {'lat':None, 'lon':None, 'alt_wgs84':None,
'roll':None, 'pitch':None, 'yaw':None}
self.pos_target = {'lat':None, 'lon':None, 'alt_wgs84':None}
self.fence = {}
self.mission = {}

self.web_server_thread = None
self.socket_server_thread = None
self.server_thread = None

self.run_web_server()
self.run_socket_server()
self.run_server()

if self.cesium_settings.openbrowser:
self.open_display_in_browser()


def run_socket_server(self):
# log.startLogging(sys.stdout)
self.factory = WebSocketServerFactory(u"ws://0.0.0.0:9000")
def run_server(self):
# log.startLogging(sys.stdout)

# create a Twisted Web resource for our WebSocket server
self.factory = WebSocketServerFactory(u"ws://0.0.0.0:5000")
self.factory.protocol = ServerProtocol
self.factory.setProtocolOptions(maxConnections=100)
self.factory.data = {}
self.factory.message_queue = Queue.Queue()
wsResource = WebSocketResource(self.factory)

reactor.listenTCP(9000, self.factory)
self.socket_server_thread = threading.Thread(target=reactor.run, args=(False,))
self.socket_server_thread.daemon = True
self.socket_server_thread.start()
# create a Twisted Web WSGI resource for our Flask server
wsgiResource = WSGIResource(reactor, reactor.getThreadPool(), cesium_web_server.app)

def stop_socket_server(self):
if self.socket_server_thread is not None:
reactor.callFromThread(reactor.stop) # Kill the socket server talking to the browser
while self.socket_server_thread.isAlive():
time.sleep(0.01) #TODO: handle this better...
# create a root resource serving everything via WSGI/Flask, but
# the path "/ws" served by our WebSocket stuff
rootResource = WSGIRootResource(wsgiResource, {b'ws': wsResource})

# create a Twisted Web Site and run everything
site = Site(rootResource)
reactor.listenTCP(5000, site, interface='0.0.0.0')
self.server_thread = threading.Thread(target=reactor.run, args=(False,))
self.server_thread.daemon = True
self.server_thread.start()

def run_web_server(self):
'''optionally launch the webserver on the local machine'''
if self.cesium_settings.localwebserver:
from app import cesium_web_server
self.web_server_thread = threading.Thread(target=cesium_web_server.start_server, kwargs={'debug':self.cesium_settings.debug})
self.web_server_thread.daemon = True
self.web_server_thread.start()
self.mpstate.console.writeln('MAVCesium display loaded at http://127.0.0.1:5000/', fg='white', bg='blue')

def stop_web_server(self):
if self.web_server_thread is not None:
urllib2.urlopen('http://127.0.0.1:5000/exit') # Kill the web server
while self.web_server_thread.isAlive():
def stop_server(self):
if self.server_thread is not None:
reactor.callFromThread(reactor.stop) # Kill the server talking to the browser
while self.server_thread.isAlive():
time.sleep(0.01) #TODO: handle this better...

def open_display_in_browser(self):
Expand Down Expand Up @@ -278,8 +277,7 @@ def idle_task(self):

def unload(self):
'''unload module'''
self.stop_socket_server()
self.stop_web_server()
self.stop_server()


def init(mpstate):
Expand Down
21 changes: 7 additions & 14 deletions app/cesium_web_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
Samuel Dudley
Jan 2016
'''




import os, sys, json, uuid

from flask import (
Expand Down Expand Up @@ -40,25 +42,16 @@ def get_current_context():
markers = False
return render_template('context_menu.html', markers=markers)

@app.route('/exit', methods=["GET"])
def exit():
shutdown_server()
return "web server shutting down..."

def shutdown_server():
shutdown_func = request.environ.get('werkzeug.server.shutdown')
shutdown_func()

def start_server(debug = False):

if not debug:
import logging
log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)

app.run(host='0.0.0.0',port=5000)

if __name__ == '__main__':
start_server()


4 changes: 2 additions & 2 deletions app/static/DST/js/websocket.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ function check_websocket(){
};

function open_websocket() {
socket = new WebSocket("ws://127.0.0.1:9000");
socket = new WebSocket("ws://127.0.0.1:5000/ws");
socket.binaryType = "arraybuffer";
socket.onopen = function() {
console.log("WebSocket connected!");
isopen = true;
}
socket.onerror = function(e) {
console.log("WebSocket connection error.");
console.log("WebSocket connection error:", e);
socket = null;
isopen = false;
}
Expand Down

0 comments on commit 72f1a9b

Please sign in to comment.