This repository was archived by the owner on Sep 30, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.py
More file actions
190 lines (144 loc) · 5.5 KB
/
server.py
File metadata and controls
190 lines (144 loc) · 5.5 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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
from cli_parameters import server_parameters
from responses import host_actions
from bots import bot
import threading
import socket
import random
import time
import json
import sys
try:
# Connection Data
host = str(server_parameters().get("host"))
port = int(server_parameters().get("port"))
# Initializing Connection
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen()
print(f"Server is running on ({host}: {port})")
except ValueError as v:
print("Given parameters are not valid.")
print(v)
sys.exit(2)
except ConnectionError as c:
print("Cannot connect to the given address.")
print(c)
sys.exit(2)
except Exception as e:
print("Something went wrong.")
print(e)
sys.exit(2)
# Dynamic Data
aliases = []
clients = []
history = []
def receive(client):
while True:
try:
message = client.recv(1024)
# When clients send a message with the keyword quit
# Terminate their connection
if 'quit' in message.decode():
client_to_quit = message.decode()[5:]
if client_to_quit in aliases:
index = aliases.index(client_to_quit)
client_quitting = clients[index]
client_quitting.close()
continue
# A message from one client will be sent to all the other clients
# These messages are stored in an array as bytes
# With this, newly connected clients will be able to read past conversations
else:
history.append(message)
broadcast(message, None)
except:
# If the client disconnects, remove them from the clients array
index = clients.index(client)
clients.remove(client)
client.close()
# Sends feedback to other clients that a client has left the chat room
alias = aliases[index]
broadcast_msg = f"({get_time()}) - [{alias}] left the chat!"
broadcast(broadcast_msg.encode(), None)
history.append(broadcast_msg.encode())
print(f"\n[{alias}] terminated the connection!")
aliases.remove(alias)
# If all clients disconnects, close the server
if not clients:
print("\nAll clients has been disconnected.")
print(f"Closing server...")
time.sleep(2)
print("Server closed!")
time.sleep(2)
server.close()
break
def accept():
while True:
try:
# Accept Connections
client, address = server.accept()
print(f"\nA connection to {address} has been established.")
# Request and store an alias
client.send('alias'.encode())
alias = client.recv(1024).decode()
# Request a new alias if the given alias is already taken
while alias in aliases:
client.send(f"{alias} taken".encode())
alias = client.recv(1024).decode()
if alias not in aliases:
break
elif alias == 'error':
break
# Terminates connection to invalid clients
if alias == 'error' or not alias:
print(f"The Connection to {address} has been terminated.")
client.close()
continue
# Adds valid clients to the following lists
else:
aliases.append(alias)
clients.append(client)
# Displays connection feedback to the server and the new client
print(f"The client at {address} connected to the server with the alias [{alias}].")
client.send(f"\nYou are now online with the alias [{alias}].\n".encode())
time.sleep(.5)
# Send a suggestion
client.send(server_suggestion.encode())
time.sleep(.5)
# Send connection feedback to other clients
connection_msg = f"({get_time()}) - [{alias}] joined the chat!".encode()
broadcast(connection_msg, client)
# Send past conversations to newly connected clients
send_history(client)
time.sleep(.5)
client.send('end of history'.encode())
history.append(connection_msg)
# Handles every clients' message on a thread
receive_thread = threading.Thread(target=receive, args=(client,))
receive_thread.setName('Receive Thread')
receive_thread.start()
except:
# If something goes wrong, break the loop
break
# Sends the past conversations of other clients
def send_history(client):
for conversation in history:
client.send(conversation)
time.sleep(.5)
# Sends messages from one client to all the other clients
def broadcast(message, client_to_skip):
for client in clients:
if client == client_to_skip:
continue
client.send(message)
# Returns current time
def get_time():
return time.strftime("%H:%M", time.localtime())
# Generates a suggestion
def generate_server_suggestion():
reaction = ['negative', 'positive', 'neutral']
return bot('Host', random.choice(host_actions), random.choice(reaction))
# Generates a server suggestion and is converted to a json object
server_suggestion = json.dumps(generate_server_suggestion())
# Run accept
accept()