使用Twisted框架作聊天室

首先須要下載react

py -3 -m pip install twisted服務器

py -3 -m pip install  Pywin32app

# 服務端
# encoding=utf-8
from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineReceiver  # 事件處理器
from twisted.internet import reactor


class Chat(LineReceiver):
    message_dict = {}

    def __init__(self, users):
        self.users = users
        self.name = None
        self.state = "GETNAME"

    def connectionMade(self):  # 鏈接開始,且開始作處理
        if self.name is None:
            self.sendLine("請輸入用戶名".encode("utf-8"))

    def connectionLost(self):
        if self.name in self.users:
            del self.users[self.name]
            try:
                del Chat.message_dict[self.name]
            except:
                print("刪除用戶的聊天記錄失敗")

    def lineReceived(self, line):  # 對返回內容開始作處理
        if self.state == "GETNAME" and "getmessage" not in line.decode("utf-8"):  # 根據狀態開始選擇不一樣得內容處理
            print("line:", line)
            self.handle_GETNAME(line.decode("utf-8"))
        else:
            self.handle_CHAT(line.decode("utf-8"))

    def handle_GETNAME(self, name):
        if name in self.users:
            self.sendLine("謝謝,請作另外得選擇.\n".encode("utf-8"))  # 每一個用戶只能有一個聊天通訊存在
            return
        self.sendLine(("歡迎, %s!\n" % name).encode("utf-8"))
        self.name = name
        self.users[name] = self
        self.state = "CHAT"

    def handle_CHAT(self, message):  # 對正在聊天得用戶進行發送消息

            if ":" in message and "getmessage" not in message:
                username = message.split(":")[0]
                if username not in Chat.message_dict:
                    Chat.message_dict[username] = []

                Chat.message_dict[username].append(message)
                print(message, "---->", "增長了用戶發送的消息:%s" %message , "\n")
                return
            elif "getmessage" in message:
                username = message.split(":")[0]
                print("*"*2,username,Chat.message_dict)
                if (username  not in Chat.message_dict) or  Chat.message_dict[username] == []:
                    self.users[username].sendLine("沒有別人給你發送的數據".encode("utf-8"))
                    print(message,"---->","沒有別人給你發送的數據","\n")
                    return
                message_indict=Chat.message_dict[username].pop(0)
                print(message_indict)
                send_message = message_indict.split(":")[1]
                username = message_indict.split(":")[0]
                if username in self.users:
                    print(username,self.users[username],self.users[username].name)
                    self.users[username].sendLine(("%s:%s" % (self.name, send_message)).encode("utf-8"))
                return
            elif message.strip() =="list":
                print("list response")
                self.sendLine((str([username for username in self.users]) + "\n").encode("utf-8"))
                print(message, "---->", (str([username for username in self.users]) + "\n"),"\n")
                return
            elif message.strip() =="bye":
                print("list response")
                self.sendLine(("Bye from server!\n").encode("utf-8"))
                print(message, "---->", (str([username for username in self.users]) + "\n"),"\n")
                return
            else:
                send_message = ("請指定用戶名,按照格式‘用戶名:消息’來進行發送。\n或者輸入list查看當前登陸用戶\n輸入getmessage\n")
                # print (type(send_message))
                self.sendLine(send_message.encode("utf-8"))
                print(message, "---->", send_message, "\n")
                return


class ChatFactory(Factory):
    def __init__(self):
        self.users = {}  # # 將全部與服務器端鏈接的對象存放到此字典中,全部的實例都可以使用此字典獲取全部的鏈接對象

    def buildProtocol(self, addr):
        return Chat(self.users)


if __name__ == '__main__':
    reactor.listenTCP(1200, ChatFactory())
    print("開始進入監聽狀態...")
    reactor.run()
#客戶端
# socket client end
from socket import *
import time
s = socket(AF_INET, SOCK_STREAM)
remote_host = gethostname()
print ('remote_host:', remote_host)
port = 1200
s.connect((remote_host, port))  # 發起鏈接
print (u"鏈接從", s.getsockname())  ##返回本地IP和端口
print (u"鏈接到", s.getpeername())  ##返回服務端IP和端口

print (u'從服務器返回消息:')
print (s.recv(1200).decode("utf-8").strip())

username = input("請輸入你要使用的英文用戶名:\n")
s.send(('%s\r\n' %username.strip()).encode("utf-8"))  # 發送一行字符串(以\r\n 結束)到服務器端
print (u'從服務器返回消息:')
print (s.recv(1200).decode("utf-8").strip())
print("*"*50)
print("""查看當前登陸用戶列表的命令:list
查看別人給你發送的消息命令要求:getmessage 
給別人發送消息的數據格式:username:要發送的消息  
""")
print("*"*50)


while 1:
    send_message=input("請輸入發送的信息:\n")    
    if send_message=="getmessage" :
        s.send(('%s:%s\r\n' %(username,send_message)).encode("utf-8"))
        print (u'從服務器返回消息:')
        print (s.recv(1200).decode("utf-8").strip())
    elif send_message=="list":
        s.send(('%s\r\n' %send_message).encode("utf-8"))
        print (u'從服務器返回消息:')
        print (s.recv(1200).decode("utf-8").strip())
    elif send_message=="bye":
        s.send(('%s\r\n' %send_message).encode("utf-8"))
        print (u'從服務器返回消息:')
        print (s.recv(1200).decode("utf-8").strip())
        s.close()
        break
    else:
        s.send(('%s\r\n' %send_message.strip()).encode("utf-8"))
        time.sleep(1)
        continue
相關文章
相關標籤/搜索