/
server.py
executable file
·115 lines (94 loc) · 4.07 KB
/
server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import socket as sockt
from threading import Thread
import time
from flask import Flask, request, jsonify
import json
import sys
class Client:
def __init__(self, connection, address):
self.connection = connection
self.address = address
self.ID = None
def send(self, data):
self.connection.send(data.encode())
def __str__(self):
return str(self.connection) + str(self.address) + "=" + str(self.ID)
class Notification:
def __init__(self, destinationID, sourceID, message):
self.destinationID = destinationID
self.sourceID = sourceID
self.message = message
def __str__(self):
return str(self.destinationID) + ", " + str(self.sourceID) + ", " + str(self.message)
def __iter__(self):
yield "destinationID", self.destinationID
yield "sourceID", self.sourceID
yield "message", self.message
class Server:
clients = []
flaskApp = Flask(__name__)
notifications = {}
def __init__(self):
# Setup broadcast service
self.broadcastThread = Thread(target=self.broadcast)
self.broadcastThread.setDaemon = True
self.broadcastThread.start()
# Setup notification registration server
self.notificationRegistrationServerThread = Thread(target=self.startNotificationRegistrationService, args=('0.0.0.0', '8080',))
self.notificationRegistrationServerThread.setDaemon = True
self.notificationRegistrationServerThread.start()
# Start accepting clients
self.startAcceptingClients('0.0.0.0', 5000)
def removeNotificationForClient(self, notification, client):
notifications = Server.notifications[client.ID].remove(notification)
if len(notifications) == 0:
Server.notifications.pop(client.ID, None)
def removeClient(self, client):
Server.clients.remove(client)
def handleNewClient(self, client):
clientID = client.connection.recv(128)
client.ID = clientID.decode()
print("New Client Connected: ", client)
def startAcceptingClients(self, host, port):
self.socket = sockt.socket(sockt.AF_INET, sockt.SOCK_STREAM)
print("Starting Server...")
print("Waiting for clients...")
self.socket.bind((host, port))
self.socket.listen(5)
while True:
connection, address = self.socket.accept()
client = Client(connection, address)
Server.clients.append(client)
thread = Thread(target=self.handleNewClient, args=(client,))
thread.setDaemon = True
thread.start()
def startNotificationRegistrationService(self, host, port):
self.flaskApp.run(host=host, port=port)
@flaskApp.route('/register', methods=['POST'])
def register():
data = request.get_json()
notification = Notification(data["destinationID"], data["sourceID"], data["message"])
try:
Server.notifications[notification.destinationID].append(notification)
except Exception as error:
Server.notifications.update({notification.destinationID: [notification]})
return jsonify(dict(notification))
def broadcast(self):
while True:
for client in Server.clients:
try:
notifications = Server.notifications[client.ID]
except Exception as error:
# When there is clients but not notification for them
continue
for notification in notifications:
try:
client.send(json.dumps(dict(notification)))
notifications.remove(notification)
except Exception as error:
print(str(error) + ": %s disconnected" % (client.ID))
client.connection.close()
Server.removeClient(client)
time.sleep(0.1)
if __name__ == "__main__":
server = Server()