-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconnection.py
100 lines (83 loc) · 3.13 KB
/
connection.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
import socket
import tornado.gen
import tornado.ioloop
import tornado.iostream
import tornado.tcpserver
import models
import json
import traceback
class Connection:
"""
Representation of a player's connection to the daily dungeon server
This connection will receive messages, which are parsed by the event
handler, and will also maintain an in-memory representation of the player
on the server.
"""
client_id = 0
def __init__(self, server, stream):
super().__init__()
# increment the unique id of the connection
Connection.client_id += 1
self.id = -1*Connection.client_id
self.stream = stream
self.server = server
# initialize the socket type
self.stream.socket.setsockopt(
socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
self.stream.socket.setsockopt(
socket.IPPROTO_TCP, socket.SO_KEEPALIVE, 1)
# add a callback for disconnection
self.stream.set_close_callback(self.on_disconnect)
self.player = models.Player(self)
self.peer = 'closed'
@tornado.gen.coroutine
def on_disconnect(self):
"""
Executed function when the socket closes.
"""
# for now we currently have no functionality planned for disconnection
self.server.connections.remove(self)
self.server.floors[self.player.floor].remove(self.player)
# tell others about the removal of this player
# only if they're not dead, else it'll show their tombstone
yield self.server.event_handler.handle_message(self.player, {
'type': 'disconnect'
})
self.log("goodbye")
@tornado.gen.coroutine
def dispatch_client(self):
"""
Loop that handles receiving messages from the socket
"""
try:
while True:
# messages are read in by line
line = yield self.stream.read_until(b'\n')
# read the json from the message
try:
payload = tornado.escape.json_decode(line)
# handle the event type associated with the message
yield self.server.event_handler.handle_message(self.player, payload)
except Exception as e:
traceback.print_exc()
self.log("message must be json")
except tornado.iostream.StreamClosedError:
# handle closed processing within on_disconnect instead of here
pass
@tornado.gen.coroutine
def on_connect(self):
"""
Performs on connection processing
"""
# add this connection into the server to keep track of
self.server.connections.append(self)
# identify the connection's address (used for debugging purposes)
self.peer = 'closed'
try:
self.peer = '%s:%d' % self.stream.socket.getpeername()
except Exception:
pass
# yeild the process to start handling client messages
yield self.dispatch_client()
def log(self, msg):
print('[connection {}] {}'.format(self.peer, msg))