-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.py
More file actions
133 lines (107 loc) · 3.18 KB
/
server.py
File metadata and controls
133 lines (107 loc) · 3.18 KB
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import socket
import json
import sys
from threading import Thread
class Server:
def __init__(self, game, port):
self.conn = socket.socket()
self.conn.bind(('0.0.0.0', port))
self.conn.listen(5)
self.game = game
self.clients = []
self.running = True
self.listener = Thread(target=self.listen)
self.listener.start()
try:
while True:
pass
except KeyboardInterrupt:
self.terminate()
def terminate(self):
print('Terminating')
self.running = False
self.conn.shutdown(socket.SHUT_RDWR)
self.conn.close()
for client in self.clients:
self.term_client(client)
def listen(self):
while self.running:
try:
client = Client(self, *self.conn.accept())
self.clients.append(client)
except socket.error as err:
if self.running:
raise err
def handle(self, client, data):
data = json.loads(data.decode())
clients, data = self.game.handler[
data['action']](client, data, self.clients)
self.send(clients, json.dumps(data).encode())
def send(self, clients, data):
print('Sending data')
for client in clients:
try:
client.conn.send(data)
except socket.error:
self.term_client(client)
def term_client(self, client):
try:
client.terminate()
except socket.error:
print('Exception during client termination')
finally:
print('Removing client from list')
self.clients.remove(client)
class Client:
def __init__(self, server, conn, addr):
print('New client connected')
self.server = server
self.conn = conn
self.addr = addr
self.data = {
'x': 0,
'y': 0
}
self.id = 0
self.listener = Thread(target=self.listen)
self.listener.start()
def listen(self):
while self.server.running:
try:
data = self.conn.recv(1024)
if len(data):
self.server.handle(self, data)
else:
self.terminate()
break
except socket.error as err:
if self.server.running:
raise err
def terminate(self):
self.conn.shutdown(socket.SHUT_RDWR)
self.conn.close()
print('Terminated client')
class Game:
def __init__(self):
self.handler = {
'move': self.move
}
def move(self, client, data, clients):
client.data['x'] += data['x']
client.data['y'] += data['y']
return clients, {
'action': 'move',
'client': client.id,
'x': client.data['x'],
'y': client.data['y']
}
def main():
try:
port = int(sys.argv[1])
except IndexError:
print('Usage: python {} port'.format(sys.argv[0]))
sys.exit()
game = Game()
server = Server(game, port)
if __name__ == '__main__':
main()