-
Notifications
You must be signed in to change notification settings - Fork 4
/
server_communication.py
122 lines (99 loc) · 4.06 KB
/
server_communication.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
116
117
118
119
120
121
122
import socket
import threading
import time
from server_messages import NetMessage, NetMessageType
from logger import log
class IncomingMessage(object):
def __init__(self, id, type, data, size, addrFrom):
self.id = id
self.type = type
self.data = data
self.size = size
self.addrFrom = addrFrom
class ServerCommunication(object):
Instance = None
def __init__(self):
ServerCommunication.Instance = self
self.socket = None
self.isConnected = False
self.incomingMessages = []
self._tryToConnect = False
self._quit = False
self.thread = threading.Thread(target=self._threadFuncReadIncoming)
self.thread.start()
def connectTo(self, ip, port):
if self.isConnected:
self.disconnect()
self.addr = (ip, port)
log.info("Connecting to server... (%s:%s)" % (ip, port))
if self.socket is None:
self.socket = socket.socket()
self._tryToConnect = True
def _threadFuncReadIncoming(self):
while True:
try:
if self._quit:
break
if not self.isConnected and self._tryToConnect:
try:
self.socket.connect(self.addr)
self.isConnected = True
log.info("Connected to server!")
except Exception as ex:
log.warn("Failed to connect to server: %s", ex.__class__.__name__)
log.debug("... reason for failure: %s", ex)
self.isConnected = False
self._tryToConnect = False
if not self.isConnected:
time.sleep(0.5)
if self.isConnected:
# Get header
data, addr = self.socket.recvfrom(NetMessage.HEADER_LENGTH)
msgid = int(data[:4])
msgsize = int(data[5:])
type = NetMessageType.CLASS_LOOKUP[msgid]
# Get body based on header
totalSizeReceived = 0
data = b''
while totalSizeReceived < msgsize:
data_part, addr = self.socket.recvfrom(msgsize - totalSizeReceived)
data += data_part
totalSizeReceived = len(data)
# Completed receiving full message
log.debug("Received message '%s' (%sbytes)", type.__name__, msgsize)
inMsg = IncomingMessage(msgid, type, data, msgsize, addr)
self.incomingMessages.append(inMsg)
except (ConnectionResetError, ConnectionAbortedError):
log.debug("Connection lost")
self.isConnected = False
self.socket = None
except Exception as ex:
log.error("Exception in thread: %s", ex.__class__.__name__)
log.debug("... exception details: %s", ex)
break
self.isConnected = False
log.debug("THREAD ENDED!")
def disconnect(self):
self._tryToConnect = False
if self.isConnected:
log.debug("Disconnecting")
self.isConnected = False
self.socket.close()
def stopThread(self):
self._quit = True
def processIncomingMessages(self):
if not len(self.incomingMessages):
return
for msg in self.incomingMessages:
log.debug("Reading message '%s' (%sbytes)", msg.type.__name__, msg.size)
msgClass = NetMessageType.CLASS_LOOKUP[msg.id]
msgInstance = msgClass()
msgInstance.read(msg.data.decode("utf-8"))
# Empty the list
self.incomingMessages = []
def sendMessage(self, msg):
if not self.isConnected:
return
msgSerialized = msg.serialize()
log.debug("Sending message '%s' (%sbytes)", msg.__class__.__name__, len(msgSerialized))
self.socket.send(msgSerialized.encode('utf-8'))