-
Notifications
You must be signed in to change notification settings - Fork 11
/
ChatServer.py
194 lines (166 loc) · 5.25 KB
/
ChatServer.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
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
191
192
193
194
#/usr/bin/python2.7
# -*- coding: utf-8 -*-
# Author: Hurray([email protected])
# Date: 2017.05.28
from socket import *
from time import ctime
import threading
import json
global HOST
global PORT
global BUFSIZ
global ADDR
class User():
def __init__(self, address, tcpCliSock):
self.address = address
self.tcpCliSock = tcpCliSock
class Handle():
usernames = {} # user: usernames
def __init__(self, user):
self.user = user
@staticmethod
def getUser(username):
def getKey(list, value):
return [k for k,v in d.items() if v == value][0]
return getKey(Handle.usernames, username)
@staticmethod
def delUsername(username):
try:
user = Handle.getUser(username)
Handle.delUser(user)
except:
pass
@staticmethod
def delUser(user):
try:
Handle.usernames.pop(user)
except Exception as e:
print e
@staticmethod
def sendSocketToUsers(userList, data):
jData = json.dumps(data)
for user in userList:
user.tcpCliSock.send(jData)
print "__sendToAll__" + jData
@staticmethod
def sendSocketToNames(usernameList, data):
"""向用户列表发送相同的数据包"""
def getKeys(list, valueList):
return [k for k,v in list.items() if v in valueList]
userList = getKeys(Handle.usernames, usernameList)
Handle.sendSocketToUsers(userList, data)
def sendSocketToMe(self, data):
"""给本用户发送信息包"""
jData = json.dumps(data)
self.user.tcpCliSock.send(jData)
print '__send__' + jData
def login(self, data):
"""处理登录信息包"""
# already login
if self.user in Handle.usernames.keys():
data['status'] = False
data['info'] = "您已经登录了"
# username in use
elif data['username'] in Handle.usernames.values():
data['status'] = False
data['info'] = "该用户名已被占用"
else:
data['status'] = True
Handle.usernames[self.user] = data['username']
self.sendSocketToMe(data)
def ping(self, data):
"""ping pong!"""
data = {'type': 'pong'}
self.sendSocketToMe(data)
def list(self, data):
"""获取在线用户列表"""
nameList = Handle.usernames.values()
data['list'] = nameList
self.sendSocketToMe(data)
def singleChat(self, data):
"""私聊"""
toUsername = data['to']
self.sendSocketToNames([toUsername], data)
def groupChat(self, data):
"""群聊(公共聊天)"""
userList = [user for user in Handle.usernames]
self.sendSocketToUsers(userList, data)
def logout(self, data):
"""登出"""
print "用户"+ Handle.usernames[self.user] +"登出"
Handle.delUser(self.user)
def __main__(self, data):
"""处理信息包"""
type = data['type']
switch = {
"login": self.login,
"ping": self.ping,
"list": self.list,
"singleChat": self.singleChat,
"groupChat": self.groupChat,
"logout": self.logout
}
try:
return switch[type](data)
except Exception as e:
print e
data['status'] = False
data['info'] = "未知错误"
return data
class ClientThread(threading.Thread):
def __init__(self, user):
threading.Thread.__init__(self)
self.user = user
def run(self):
try:
handle = Handle(self.user) # handle input
while True:
jData = self.user.tcpCliSock.recv(BUFSIZ)
data = json.loads(jData)
print "___receive___" + jData
if data['type'] == 'logout':
break
else:
handle.__main__(data)
except Exception as e:
print "连接中断"
print e
finally:
name = Handle.usernames[self.user]
print "用户"+ str(name) +"登出"
Handle.delUser(self.user)
self.user.tcpCliSock.close()
def stop(self):
try:
self.user.tcpCliSock.shutdown(2)
self.user.tcpCliSock.close()
except:
pass
class Server():
def __main__(self):
tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)
threads = []
while True:
try:
print 'Waiting for connection...'
tcpCliSock, addr = tcpSerSock.accept()
print '...connected from:', addr
user = User(addr, tcpCliSock)
clientThread = ClientThread(user)
threads += [clientThread]
clientThread.start()
except KeyboardInterrupt:
print 'KeyboardInterrupt:'
for t in threads:
t.stop()
break
tcpSerSock.close()
if __name__ == '__main__':
HOST = ''
PORT = 8945
BUFSIZ = 1024
ADDR = (HOST, PORT)
server = Server()
server.__main__()