-
Notifications
You must be signed in to change notification settings - Fork 0
Server : 3 ClientManager
ClientManager is a child class of WebSocket. It is used to connect to client's react web-application that serves as an interface for a video stream and a controller for a bike. ClientManager.py is located in server/ServerApplication/component/MeansManager.py
Run a Thread that will keep this class running. This code is located at server/ServerApplication/urls.py.
ClientManager.py.initManager() # line 18ClientManager is a web socket server so it needs a port. You can customize its port number here.
meansport = 7001. # line 20This function will transform the Client model in models.py into a dictionary of string.
@staticmethod # line 92
def clienttoString(client):
info = dict()
info["id"] = client.id
info["autoritytag"] = client.autoritytag
info["username"] = client.username
info["password"] = ""
info["email"] = client.email
return json.dumps(info)This function will check if the token is valid or not. If this token has been created for 5 minute, it will be invalid.
@staticmethod # line 102
def validateToken(token):
diff = datetime.datetime.now() - ClientManager.__tokenTimer[token]
form = diff.total_seconds()
return diff >= 300This function will refresh a token. It will always be called when a user does some action. For example, request for a video stream or ask for control of a bike.
@staticmethod. # line 108
def refreshToken(token):
ClientManager.__tokenTimer[token] = datetime.datetime.now()This function will validate the username and password sent by a user. Then give the user a new token to access other services.
@staticmethod # line 112
def login(request):
data = json.loads(request)
# User can log in with either email or username
if ("username" in data): # Find a client with this username.
userlist = Client.objects.filter(username=data["username"], password=data["password"])
elif ("email" in data): # Find a client with this email.
userlist = Client.objects.filter(email=data["email"], password=data["password"])
else:
return ClientComment.generateLoginComment("Login Unsuccessful.")
if (len(userlist) != 0):
loginUser = userlist[0]
else:
return ClientComment.generateLoginComment("Login Unsuccessful.")
if (loginUser.id in ClientManager.__loginUser): # If the user already login, assign new token to the user. (In case one user login at the same time, only the newest user will be valid)
authToken = ClientManager.__loginUser[loginUser.id]
else:
authToken = str(uuid.uuid4()).replace("-", "") # Generate new token.
ClientManager.__loginUser[authToken] = loginUser.id # Load the token into the dictionary.
token = ClientComment.generateLoginComment(authToken)
ClientManager.refreshToken(authToken) # Refresh the loaded token.
userlist[0].password = "" # Empty the user's password before sending. (Security measure)
token['info'] = ClientManager.clienttoString(userlist[0]) # Turn user's data into a dictionary of string.
return token # Return the data.In case a user don't want to login. That user will be automaically logged in as a visitor.
@staticmethod # line 143
def loginVisitor(request):
data = json.loads(request)
if("visitorid" in data):
authToken = str(uuid.uuid4()).replace("-", "") # Generate a new token without having to verify anything.
ClientManager.__loginUser[authToken] = "id"+str(uuid.uuid4()) # Save that token with new randomize id. (The id is not important because every survice only need )
ClientManager.refreshToken(authToken)
token = ClientComment.generateLoginComment(authToken)
return token
return NoneCheck if the bike you are looking for is connected to the server or not.
@staticmethod # line 155
def checkbike(request):
data = json.loads(request)
pack = dict()
pack["isBikeOnline"] = "Offline"
pack["bikeid"] = data["bikeid"]
if("bikeid" in data): # If the bike is connected give it "Online" status.
if(data["bikeid"] in BicycleManager.bicycleid):
pack["isBikeOnline"] = "Online"
comment = ClientComment.generateCheckBikeComment(pack)
return commentThis function will send the room id (unique id) of a room that a client needs to join in order to receive the video stream.
@staticmethod. # line 169
def askforvideo(request):
data = json.loads(request)
data['token'] = ClientManager.clientroom[data['bikeid']] # Give the client room id based on an id of the targeted bike.
return ClientComment.generateAskForVideo(data)Bind the user to bike. This function will validate the token before sending it to BikeManager.py.
@staticmethod # line = 190
def bindtobike(request,token):
data = json.loads(request)
if(token in ClientManager.__loginUser):
result = BicycleManager.bindToBike(data['status'],data['bikeid'],ClientManager.__loginUser[token])
if(type(result) == float): # If the bike can not be joined. Result will be float, which is the amount of seconds that you need to wait.
return ClientComment.generateAskForControl(float(result))Send user inputs to the selected bike, which has to be sent to BikeManager.py
@staticmethod # line = 183
def givedirection(request,token):
data = json.loads(request)
if (token in ClientManager.__loginUser): # If the given token is valid, send the input to BicycleManager.
BicycleManager.sendDirection(data["direction"],data["bikeid"],ClientManager.__loginUser[token])ClientComment is a class that provides a template to create packages of information to be sent to and receive from clents. ClientComment.py is located in server/ServerApplication/component/Comment/ClientComment.py
class ClientComment:
Login = 1 # These integers are used to identify what survice that the package is sent for.
CheckBike = 2
AskForVideo = 3
GiveDirection = 4
AskForControl = 5
Visitorlogin = 6
@staticmethod
def generateLoginComment(comment):
data = dict()
data['code'] = ClientComment.Login # For above integers.
data['pack'] = comment # For the information that need to be sent with this package.
return data