一、聊天室的整体架构
1.twisted:实现服务端,以及事件驱动
- Twisted是用Python实现的基于事件驱动的网络引擎框架。
2.socket:实现客户端,以及事件驱动
3.tkinter:实现客户端界面
4.MySQL:用户信息存储,以及登录、注册逻辑处理
二、聊天室的具体实现
1.服务端实现事件驱动
from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor
from model import login_model,register_model,chat_model
import json
class Chat(LineReceiver):
def __init__(self, users):
self.users = users
def connectionLost(self, reason):
if self in self.users.keys():
del self.users[self]
def dataReceived(self, data):
data = data.decode('utf-8')
data_dict = json.loads(data)
if data_dict["type"] == "login":
login_model.login(self,data_dict)
elif data_dict["type"] == "register":
register_model.register(self,data_dict)
elif data_dict["type"] == "chat":
chat_model.chat(self,data_dict)
class ChatFactory(Factory):
def __init__(self):
self.users = {
}
def buildProtocol(self, addr):
print(addr)
return Chat(self.users)
if __name__ == '__main__':
reactor.listenTCP(1200, ChatFactory())
print ("开始进入监听状态...")
reactor.run()
2.服务端的逻辑处理
from db import user_db
import json
def login(self,data_dict):
account = data_dict["account"].strip()
password = data_dict["password"].strip()
data = {
}
if account and password:
code,msg,nickname = login_check(account, password)
elif not account:
code = "700001"
msg = "登录账号不能为空"
elif not password:
code = "700002"
msg = "登录密码不能为空"
if code == "000000":
self.users[self] = nickname
data["nickname"] = nickname
data["type"] = "login"
data["code"] = code
data["msg"] = msg
data = json.dumps(data)
self.sendLine(data.encode("utf-8"))
def login_check(account, password):
userInfo = user_db.checkUser(account)
if len(userInfo) == 0:
data = ("700003", "账号【%s】未注册,请注册后再登录!" % account, None)
elif password != userInfo[0][1]:
data = ("700004", "密码错误,请重新输入", None)
else:
nickname = userInfo[0][2]
data = ("000000", "账号【%s】登录成功" % account, nickname)
return data
from db import user_db
import json
def register(self, data_dict):
account = data_dict["account"].strip()
password = data_dict["password"].strip()
nickname