1
1
#!/usr/bin/env python3
2
2
3
3
import io
4
+ import os
4
5
import json
5
6
import socket
6
7
import threading
@@ -24,35 +25,72 @@ class Room:
24
25
def __init__ (self , name = "default" ):
25
26
self .clients = []
26
27
self .name = name
27
- self .filename = "/tmp/room_" + name
28
- self .write_handle = open (self .filename , "wb" )
28
+ self .msgs_file = "/tmp/room_" + name + "_msgs"
29
+ self .write_handle = open (self .msgs_file , "wb" )
29
30
self .image = Image .new ("L" , (WIDTH , HEIGHT ), 255 )
31
+ self .image_file = "/tmp/room_" + name + "_img"
30
32
self .imgdraw = ImageDraw .Draw (self .image )
33
+ self .lock = threading .Lock ()
34
+
35
+ if os .path .exists (self .image_file ):
36
+ self .image = Image .open (self .image_file )
37
+
38
+ if os .path .exists (self .msgs_file ):
39
+ with open (self .msgs_file , "rb" ) as f :
40
+ for line in f .readlines ():
41
+ msg_obj = json .loads (line )
42
+ x , y , px , py = (
43
+ msg_obj ["x" ],
44
+ msg_obj ["y" ],
45
+ msg_obj ["prevx" ],
46
+ msg_obj ["prevy" ]
47
+ )
48
+ self .imgdraw .line (
49
+ [(px , py ), (x , y )],
50
+ fill = msg_obj ["color" ],
51
+ width = msg_obj ["width" ]
52
+ )
53
+
31
54
32
55
def __del__ (self ):
33
- self .write_handle .close ()
56
+ with self .lock :
57
+ self .write_handle .close ()
34
58
35
59
def add (self , client ):
36
- self .clients .append (client )
37
- self .write_handle .flush ()
60
+ with self .lock :
61
+ self .clients .append (client )
62
+ self .write_handle .flush ()
38
63
39
- with open (self .filename , 'rb' ) as f :
40
- client .conn .sendall (f .read ())
64
+ with open (self .msgs_file , 'rb' ) as f :
65
+ client .conn .sendall (f .read ())
41
66
42
67
def remove (self , client ):
43
- print ("Removing connection" , client .conn .addr )
44
- self .clients .remove (client )
68
+ with self .lock :
69
+ print ("Removing connection" , client .conn .addr )
70
+ self .clients .remove (client )
45
71
46
72
def send (self , msg_str ):
47
- for client in self .clients :
48
- try :
49
- client .conn .sendall (msg_str + b'\n ' )
50
- except :
51
- pass
73
+ with self .lock :
74
+ for client in self .clients :
75
+ try :
76
+ client .conn .sendall (msg_str + b'\n ' )
77
+ except :
78
+ pass
79
+
80
+ # make thread safe?
81
+ self .write_handle .write (msg_str + b'\n ' )
82
+ self .write_handle .flush ()
83
+
84
+ def clear (self ):
85
+ with self .lock :
86
+ self .image = Image .new ("L" , (WIDTH , HEIGHT ), 255 )
87
+ self .clear_log ()
88
+
89
+ self .send (b'{"type":"clear"}' )
90
+
91
+ def clear_log (self ):
92
+ self .write_handle .truncate ()
52
93
53
- self .write_handle .write (msg_str )
54
- self .write_handle .write (b'\n ' )
55
- self .write_handle .flush ()
56
94
57
95
58
96
_rooms = { "default" : Room (name = "default" )}
@@ -81,7 +119,13 @@ def join(self, room):
81
119
# TODO send URL with image download
82
120
83
121
def handle_message (self , msg_obj ):
84
- if msg_obj ["type" ] == "draw" and self .room :
122
+ if msg_obj ["type" ] == "join" :
123
+ self .join (msg_obj ["room" ])
124
+
125
+ if self .room == None :
126
+ return
127
+
128
+ if msg_obj ["type" ] == "draw" :
85
129
x , y , px , py = (
86
130
msg_obj ["x" ],
87
131
msg_obj ["y" ],
@@ -97,8 +141,9 @@ def handle_message(self, msg_obj):
97
141
msg_str = bytes (json .dumps (msg_obj ), encoding = 'utf8' )
98
142
with room_lock :
99
143
_rooms [self .room ].send (msg_str )
100
- elif msg_obj ["type" ] == "join" :
101
- self .join (msg_obj ["room" ])
144
+ elif msg_obj ["type" ] == "clear" :
145
+ with room_lock :
146
+ _rooms [self .room ].clear ()
102
147
103
148
def run (self ):
104
149
# self.csocket.send(bytes("Hi, This is from Server..",'utf-8'))
@@ -124,10 +169,7 @@ def run(self):
124
169
message = b""
125
170
126
171
for msg_obj in messages :
127
- try :
128
- self .handle_message (msg_obj )
129
- except Exception as e :
130
- print ("EXC" , msg_obj , e )
172
+ self .handle_message (msg_obj )
131
173
132
174
messages = []
133
175
self .conn .close ()
@@ -141,8 +183,13 @@ def get_room_image(room):
141
183
with room_lock :
142
184
if room not in _rooms :
143
185
return "room not found"
144
- im = _rooms [room ].image
145
- im .save (s , format = "png" )
186
+ room = _rooms [room ]
187
+
188
+ with room .lock :
189
+ im = room .image
190
+ im .save (room .image_file , format = "png" )
191
+ im .save (s , format = "png" )
192
+ room .clear_log ()
146
193
bytes = s .getvalue ()
147
194
return bytes
148
195
0 commit comments