Skip to content

Commit

Permalink
Merge pull request #39 from joewashear007/DevBranch
Browse files Browse the repository at this point in the history
Merged in changes from the dev branch. The master/Slave controlling is now working
  • Loading branch information
joewashear007 committed Feb 14, 2014
2 parents f878198 + 99f7218 commit 58da57f
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 38 deletions.
41 changes: 24 additions & 17 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,31 @@
# */

from server import WebSocketHttpServer
from server import WebSocketsHandler
from server import WebSocketHandler

def main():
print()
print()
print("*** Starting Websocket Server ***")
print()
print("Press Any Key To Quit...")
print()
server = WebSocketHttpServer(WebSocketsHandler, http_address=('',8000))
if server.start():
print()
server.launch_webpage()
else:
print("Error Starting Server")
i = input()
server.stop()
print("Good Bye")
run = True
print()
print()
print("*** Starting Websocket Server ***")
print()
print("Press Any Key To Quit...")
print()
server = WebSocketHttpServer(WebSocketHandler, http_address=('',8000))
if server.start():
print()
server.launch_webpage()
else:
print("Error Starting Server")
while run:
i = input("Enter Command:")
if i == "q":
server.stop()
run = False
else:
if i:
server.send(i)
print("Good Bye")

if __name__ == '__main__':
main()
main()
101 changes: 84 additions & 17 deletions server.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import struct
import shutil
import webbrowser
import json
from io import StringIO
from string import Template

Expand All @@ -29,29 +30,78 @@ def log_message(self, format, *args):
pass #Hides all messages for Request Handler

# Inherit this class to handle the websocket connection
class WebSocketsHandler(socketserver.BaseRequestHandler):
class WebSocketHandler(socketserver.BaseRequestHandler):

#-------------- Over ride these ----------------------------------------
def on_message(self, msg):
#msg is a array, decoded from JSON
#Override this function to handle the input from webcontroller
print(msg)
self.send_message("Got :" + msg)
#self.send_message("Got :" + ast.literal_eval(msg))

def handle_message(self, msg):
#only the user with the lock can control
if self._hasLock():
msg_data = json.loads(msg)
if "MASTER_REQUEST" in msg_data:
if msg_data["MASTER_REQUEST"]:
WebSocketHandler.lock_id = threading.current_thread().ident
self.send_json(dict(MASTER_STATUS=True));
print("Locking to thread: " ,WebSocketHandler.lock_id, " : ", self.id)
self.broadcast_all(dict(SLAVE=True))
else:
WebSocketHandler.lock_id = None
self.send_json(dict(MASTER_STATUS=False))
self.broadcast_all(dict(SLAVE=False))
#elif "MESSAGE" in msg_data:
# self.on_message(msg["MESSAGE"])
#else:
# print("Unknown CMD, trashing: ", msg_data)
self.on_message(msg_data)
else:
self.send_json(dict(SLAVE=True));
print("Locked, trashing: ", msg)

def on_close(self):
print("Server: Closing Connection for ", self.client_address)
self.send_message("Server: Closing Connection")

def send_message(self, message):
self.request.sendall(self._pack(message))
print("Sending: ", message)
self.send_json(dict(MESSAGE=message))

def send_json(self, data):
#sends a python dict as a json object
self.request.sendall(self._pack(json.dumps(data)))

def broadcast_all(self, data):
#send a araay converted into JSON to every thread
for t in WebSocketHandler.connections:
if t.id == self.id:
continue
t.send_json(data)

#-------------------------------------------------------------------

magic = b'258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
lock_id = None
connections = []

def _hasLock(self):
#there is no lock or the current thread has it
return (not WebSocketHandler.lock_id) or (WebSocketHandler.lock_id == self.id)



def setup(self):
#Overwrtien function from socketserver
#Init some varibles
print("\nConnection Established", self.client_address)
self.closeHandle = False
self.id = threading.current_thread().ident
self.alive = threading.Event()
self.alive.set()
WebSocketHandler.connections.append(self)

def handle(self):
#handles the handshake with the server
Expand All @@ -60,10 +110,11 @@ def handle(self):
self.handshake()
except:
print("HANDSHAKE ERROR! - Try using FireFox")
return

#return

def run(self):
#runs the handler in a thread
while 1:
while self.alive.isSet():
msg = self.request.recv(2)
if not msg or self.closeHandle or msg[0] == 136:
print("Received Closed")
Expand All @@ -77,7 +128,10 @@ def handle(self):
decoded = ""
for char in self.request.recv(length):
decoded += chr(char ^ masks[len(decoded) % 4])
self.on_message(decoded)
self.handle_message(decoded)

#WebSocketHandler.broadcast_all.wait(0.01)

self.close()

def close(self, message="Cxn Closed"):
Expand Down Expand Up @@ -172,7 +226,7 @@ def get_address(self):

def run(self):
#Overwrtien from Threading.Thread
if self.httpd is not None:
if self.httpd is not None :
self.httpd.serve_forever()
else:
print("Error! - HTTP Server is NULL")
Expand All @@ -189,19 +243,22 @@ class WebSocketTCPServer(socketserver.ThreadingMixIn, http.server.HTTPServer):
def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True):
socketserver.TCPServer.__init__(self, server_address, RequestHandlerClass, bind_and_activate)
self.handlers = []
self.daemon_threads = False
self.daemon_threads = True

def finish_request(self, request, client_address):
#Finish one request by instantiating RequestHandlerClass
print("launching a new request")
t = self.RequestHandlerClass(request, client_address, self)
print("Request:" , t)
self.handlers.append(t)
print("Num request:" ,len(self.handlers))
t.run()

def process_request(self, request, client_address):
#Start a new thread to process the request
t = threading.Thread(target = self.process_request_thread, args = (request, client_address))
t.daemon = True
t.start()

# def process_request(self, request, client_address):
# #Start a new thread to process the request
# t = threading.Thread(target = self.process_request_thread, args = (request, client_address))
# t.daemon = True
# t.start()

def get_handlers(self):
#returns the list of handlers
Expand Down Expand Up @@ -238,15 +295,22 @@ def run(self):
def stop(self):
print("Killing WebSocket Server ...")
if self.wsd is not None:
for h in self.wsd.handlers:
h.alive.clear()

self.wsd.shutdown()
print("Done")

def get_handlers(self):
#returns the list of handlers
return self.wsd.get_handlers()

def send(self, msg):
for h in self.wsd.get_handlers():
h.send_message(msg)

class WebSocketHttpServer():
def __init__(self, handler_class, http_address=('',0), ws_address=('',0) ):
def __init__(self, handler_class = WebSocketHandler, http_address=('',0), ws_address=('',0) ):
self.http_address = http_address
self.ws_address = ws_address
self.handler = handler_class
Expand Down Expand Up @@ -310,7 +374,10 @@ def start(self):
print(e)
print()
return False


def send(self, msg):
self.wsServer.send(msg)

def launch_webpage(self):
#Copies all the resource over to the temp dir
webbrowser.open(self.httpServer.get_address() + "/index.html")
Expand Down
Binary file modified test.blend
Binary file not shown.
13 changes: 12 additions & 1 deletion web/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,18 @@ button:active{
padding: 20px 20px 0px 20px;
font-weight:bold;
}

.disabled{
background: #ccc;
color: #999;
box-shadow: none;
}
.disabled:hover{
box-shadow: none;
}
.disabled:active{
box-shadow: none;
background: #ccc;
}


html,body,#wrapper {
Expand Down
42 changes: 39 additions & 3 deletions web/js/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@
Hammer.plugins.fakeMultitouch();
var s = null;
var somekeyDown = 0;
var isMaster = false;

window.onbeforeunload = close;

/* -------------------------- Websocket Fucntions ----------------------------
Functions used to handel the connection, opening, closing sendgin, and reciveing of the websocket
*/

function log(msg){
$("#DebugMsgList").append("<p>log: "+ msg + "</p>");
}
function open (e) {
$("#DebugMsgList").append("<p>Connect!</p>");
$("#ToggleCxnStatus").removeClass("danger");
Expand All @@ -27,7 +32,13 @@ function close(e) {
$("#ErrMsg").text("Not Connected").fadeIn();
};
function msg (e) {
$("#DebugMsgList").append("<p>Received: "+ e.data + "</p>");
msg_data = JSON.parse(e.data);
if (msg_data.hasOwnProperty("SLAVE")){ toggleSlave(msg_data["SLAVE"]); }
if (msg_data.hasOwnProperty("MASTER_STATUS")){
isMaster = msg_data["MASTER_STATUS"];
styleMaster();
}
log(e.data);
};
function error(e) {
$("#DebugMsgList").append("<p>Error: "+e+"</p>");
Expand All @@ -44,7 +55,7 @@ function send(key,msg){
$("#DebugMsgList").append("<p>Event: "+ data + "</p>");
}
}
function toggleConnection(){
function toggleConnection() {
//Opens and closes a conenction using the address in #CxnWSAddress
if(s){
s.close(1000, "Try to Close");
Expand All @@ -66,6 +77,30 @@ function toggleConnection(){
}
}
}
function toggleLockCommand() { send("MASTER_REQUEST", !isMaster ); }
function toggleSlave(locked) {
//Toogle the control of all commands with locked status
if(locked){
//$(".ctrlBtn").attr("disabled", true).addClass("disabled");
$(".ctrlBtn").addClass("disabled");
//$("#MasterLock").addClass("danger");
$("#ErrMsg").text("Locked").fadeIn();
}else{
//$(".ctrlBtn").attr("disabled", false).removeClass("disabled");
$(".ctrlBtn").removeClass("disabled");
//$("#MasterLock").removeClass("danger");
$("#ErrMsg").text("Locked").fadeOut();
}
}
function styleMaster(){
if(isMaster){
log("You are now Master");
$("#MasterLock").addClass("danger");
}else{
$("#MasterLock").removeClass("danger");
}

}

/* -------------------------- Document Ready Function ----------------------------
Main function, Handels all events, swipe, and keybord control
Expand Down Expand Up @@ -93,6 +128,7 @@ $(document).ready(function(){
$("#PopWrap").fadeIn();
});
$("#ToggleCxnBtn") .click( toggleConnection );
$("#MasterLock") .click( toggleLockCommand );
$("#PopWrapCloseBtn").click( function() { $("#PopWrap").fadeOut(); });
$("#DebugMsgListBtn").click( function() { $("#DebugMsgList").empty(); });
$("#ToggleControl") .click( function() {
Expand Down

0 comments on commit 58da57f

Please sign in to comment.