예제 #1
0
 def dispaly_message(self):
     s = self.server
     self.user_info.insert('end', '已连接的用户:')
     while True:
         # print('当前有{0}个线程_'.format(threading.activeCount()))
         # for i in threading.enumerate():
         #     print(i)
         client, address = s.accept(
         )  #运行至此阻塞,监听用户连接,建立连接口执行下列步骤,执行完后在此处再次阻塞,监听新用户连接
         self.connection_dict[
             address] = client  #在用户连接字典中创建一个key为(ip,端口),value为socket元素(将连接的用户对象加入到连接字典)
         # print(self.connection_dict)
         show_tips(
             self.display_info, self.pre_time_(),
             '用户: {0} 已连接,当前在线人数为{1}人'.format(address,
                                              len(self.connection_dict)),
             '').show()  #在消息窗体显示提示信息
         self.user_info.insert(
             'end', '用户 :{0}'.format(address))  #将用户插入到在线用户列表listbox组建中
         for connection in self.connection_dict:
             message = {}
             message['users'] = list(self.connection_dict.keys())
             self.connection_dict[connection].send(
                 json.dumps(message).encode())  #对所有用户发送在线用户列表
         t = threading.Thread(target=self.receive_data,
                              args=(address, ))  #将为新加入用户建立新线程,监听用户信息
         # print(t.name)
         t.start()  #启动用户子线程
예제 #2
0
    def chat_with(self):
        # print(self.private_message)
        try:
            user_index = self.user_info.curselection()[0] - 1
            user = self.userlist[user_index]
            if (tuple(user) == self.connection.getsockname()):
                show_tips(self.display_info, self.pre_time_(), '请选择非自己的私聊的对象',
                          '').show()
            else:
                try:
                    chat_data = list(
                        self.private_chat_window_dict[tuple(user)].chat_data)
                    print('之前窗口的消息记录为:{0}'.format(chat_data))
                    # 若读到了该用户的历史数据,将其放入对应的历史数据list
                    try:
                        self.chat_historydata[tuple(
                            user)] = chat_data + self.new_message[tuple(user)]
                        print('更新历史聊天记录为:{0}'.format(
                            self.chat_historydata[tuple(user)]))
                        self.new_message[tuple(user)] = []
                    except:
                        self.chat_historydata[tuple(user)] = chat_data
                    self.create_display_window(user)
                except Exception as e:
                    self.create_display_window(user)

        except Exception as e:
            # print(e)
            show_tips(self.display_info, self.pre_time_(), '请选择私聊的对象',
                      '').show()
예제 #3
0
 def display_private_message(self, user):
     try:
         for message in self.new_message[tuple(user)]:
             show_tips(
                 self.private_chat_window_dict[tuple(
                     user)].son_display_info, self.pre_time_(),
                 '用户:{0}:{1}'.format(user, message), '').show()
         self.new_message[tuple(user)] = []
     except Exception as e:
         print('显示消息出错')
예제 #4
0
    def receive_data(self, address):
        while True:
            try:
                # 如果要写私聊消息的离线显示,应该创建一个离线用户字典,当用户下线时,在离线消息字典中创建key为用户的(ip, 端口),value初始为空列表
                #当收到消息,并判断为私聊消息后,先遍历在线用户字典,检查私聊消息中的接受者是否在线,若不在线,则遍历离线用户字典,若在离线用户字典中找到
                #接受者,则在字典中接受者key对应的value中加入私聊消息
                # 每次在客户端建立连接时,遍历离线用户字典中value长度为非空的历史离线用户(这些用户存在私聊消息),若匹配上,则将用户离线列表中的消息推送给该用户。
                client = self.connection_dict[address]
                data = client.recv(1024)
                # 私聊信息中含有send_to字段,而公开信息中没有,
                # 所以若为私聊信息则运行try中的转发私聊聊天信息代码块
                try:
                    receive_message = json.loads(data.decode())
                    send_to = receive_message['send_to']
                    send_to_tuple = tuple(send_to)
                    message = receive_message['message']
                    receive_message['sender'] = address
                    for connection in self.connection_dict:
                        if (connection == send_to_tuple):
                            self.connection_dict[connection].send(
                                json.dumps(receive_message).encode()
                            )  #若在在线用户列表中找到了私聊对象,则将信息发送给他
                            break
                    self.display_info.insert('end',
                                             '{0}'.format(self.pre_time_()))
                    self.display_info.insert(
                        'end', '用户: {0}对用户: {1}发送了一条私聊消息:'.format(
                            address, send_to_tuple))  #服务端回显
                    self.display_info.insert('end', '{0}'.format(message))
                    self.display_info.insert('end', '')

                # 未找到send_to字段,运行except,广播共公开信息
                except:
                    show_tips(self.display_info, self.pre_time_(),
                              '用户: {0}: {1}'.format(address,
                                                    data.decode()), '').show()
                    self.broadcast_data(address, data.decode())  #广播公开信息

            #连接过程中出错,断开对应用户连接,将其移出连接用户列表,将新的在线用户列表发送给所有人
            except Exception as e:
                print(e)
                address_list = list(self.connection_dict.keys())
                self.user_info.delete(address_list.index(address) + 1)
                self.connection_dict.pop(address)
                show_tips(
                    self.display_info, self.pre_time_(),
                    '用户: {0} 已断开连接,当前在线人数为{1}人'.format(
                        address, len(self.connection_dict)), '').show()
                for connection in self.connection_dict:
                    message = {}
                    message['users'] = list(self.connection_dict.keys())
                    self.connection_dict[connection].send(
                        json.dumps(message).encode())
                break
예제 #5
0
 def send_message(self, *event):
     # self.display_info.insert('end', 'test')
     try:
         message = self.message_input.get('1.0', tkinter.END)
         message_length = len(message)
         self.message_input.delete('1.0', tkinter.END)
         self.connection.send(message.encode())
         show_tips(self.display_info, self.pre_time_(),
                   '{0}: {1}'.format('我', message), '').show()
     except Exception as e:
         show_tips(self.display_info, self.pre_time_(), '发送消息失败,请重试',
                   '').show()
         print(e)
예제 #6
0
 def log_out_user(self):
     try:
         # print(self.connection_dict)
         user_index = self.user_info.curselection(
         )[0] - 1  #在listbox组件中找到用户的索引
         user_address_list = [
             address for address in list(self.connection_dict.keys())
         ]  #客户端连接字典中的key列表
         user_client = self.connection_dict[
             user_address_list[user_index]]  #用上面的索引和列表找到对应的哟用户socket对象
         user_client.close()  #关闭该socket对象
         # self.connection_dict.pop(user_address[user_index])
         # print(self.connection_dict)
     except Exception as e:
         print(e)
         show_tips(self.display_info, self.pre_time_(), '当前操作失败,请选择左侧窗体的用户',
                   '').show()  #若未选中用户的提示信息
예제 #7
0
 def send_message(self, *event):
     # self.display_info.insert('end', 'test')
     try:
         data = self.message_input.get('1.0', tkinter.END)  #获取输入栏中用户的输入信息
         data_length = len(data)  #获取输入信息长度
         self.message_input.delete('1.0', tkinter.END)  #获取万必要信息后清空输入栏
         #对所有用户发送信息
         for connection in self.connection_dict:  #遍历连接字典,只取其中的key
             message = {}
             message['sender'] = '服务器'
             message['message'] = data
             self.connection_dict[connection].send(
                 json.dumps(message).encode()
             )  #以json格式对所有用户发送输入的信息,此后所有信息都已json格式发送
         show_tips(self.display_info, self.pre_time_(),
                   '{0}: {1}'.format('我', data), '').show()  #在服务器窗体显示发送的信息
     except Exception as e:
         show_tips(self.display_info, self.pre_time_(), '发送消息失败,请重试',
                   '').show()  #发送失败提示信息
         print(e)
예제 #8
0
 def chat_with(self):
     show_tips(self.display_info, self.pre_time_(), '该部分暂未写完',
               '').show()  #未写完提示信息
예제 #9
0
    def dispaly_message(self):
        self.user_info.insert('end', '已连接的用户:')
        try:
            s = self.connection
            # self.display_info.insert('end', '{0}:{1}'.format(self.connection_class.host, 'test'))
            while True:
                receive_message = json.loads(s.recv(1024).decode())
                if (len(receive_message) == 3):
                    sender = receive_message['sender']
                    message = receive_message['message']
                    # self.new_message[tuple(sender)] = []
                    try:
                        self.private_message[tuple(sender)].append(
                            message)  #尝试在私聊字典中找到该用户的私聊列表,并将新的消息加入到这个列表
                        try:
                            if (self.private_chat_window_dict[tuple(sender)].
                                    flag == True):  #如果通过选中用户创建了该用户的窗体类
                                print('用户已开启窗口')
                                try:
                                    self.new_message[tuple(sender)].append(
                                        message)
                                    print('新消息为:'.format(
                                        self.new_message[tuple(sender)]))
                                except:
                                    self.new_message[tuple(sender)] = [message]
                                self.display_private_message(sender)
                                # print(self.private_chat_window_dict[tuple(sender)])
                            else:
                                print('非第一次接收私聊消息,窗口激活过,现已关闭')
                                show_tips(
                                    self.display_info, self.pre_time_(),
                                    '收到用户:{0}一条私聊消息(如需回复,选中用户点击私聊): '.format(
                                        sender), '').show()
                                # print('尝试加入的消息为:{0}'.format(message))
                                # print('现在的消息列表为{0}'.format(self.private_message[tuple(sender)]))
                                # self.chat_historydata[tuple(sender)] = self.private_message[tuple(sender)]
                                try:
                                    self.new_message[tuple(sender)].append(
                                        '{0}'.format(self.pre_time_()))
                                    self.new_message[tuple(sender)].append(
                                        '用户:{0}:{1}'.format(sender, message))
                                    self.new_message[tuple(sender)].append('')
                                    # print('新消息为:'.format(self.new_message[tuple(sender)]))
                                except:
                                    self.new_message[tuple(sender)] = []
                                    self.new_message[tuple(sender)].append(
                                        '{0}'.format(self.pre_time_()))
                                    self.new_message[tuple(sender)].append(
                                        '用户:{0}:{1}'.format(sender, message))
                                    self.new_message[tuple(sender)].append('')
                                print('新数据为{0}'.format(
                                    self.new_message[tuple(sender)]))

                        except:  #如果未选中用户创建该用户的窗体类
                            print('非第一次接收消息,用户任未点开私聊按钮')
                            show_tips(
                                self.display_info, self.pre_time_(),
                                '收到用户:{0}一条私聊消息(如需回复,选中用户点击私聊): '.format(
                                    sender), '').show()
                            # print(self.chat_historydata[tuple(sender)])
                            self.chat_historydata[tuple(sender)] = []
                            for msg in self.private_message[tuple(sender)]:
                                self.chat_historydata[tuple(sender)].append(
                                    '{0}'.format(self.pre_time_()))
                                self.chat_historydata[tuple(sender)].append(
                                    '用户:{0}:{1}'.format(sender, msg))
                                self.chat_historydata[tuple(sender)].append('')
                            # print(self.chat_historydata[tuple(sender)])
                    except Exception as e:  #如果尝试失败,则在用户私聊消息字典中新建该用户的私聊消息列表,并将新消息加入,同时初始化对应用户历史消息列表为空
                        self.private_message[tuple(sender)] = []
                        self.private_message[tuple(sender)].append(message)
                        self.historydata[tuple(sender)] = []
                        # print(self.private_message[tuple(sender)])
                        try:
                            if (self.private_chat_window_dict[tuple(
                                    sender)].flag == True
                                ):  #之前创建了对应用户的窗体类,但是未创建对应用户的消息类
                                print('第一次收到私聊消息,用户已经点击过私聊按钮')
                                try:
                                    self.new_message[tuple(sender)].append(
                                        message)
                                    print('新消息为:'.format(
                                        self.new_message[tuple(sender)]))
                                except:
                                    self.new_message[tuple(sender)] = [message]
                                self.display_private_message(sender)
                            else:  #不存在未创建消息类的情况下将窗口关闭的情况。
                                print('程序不会走到这')
                        except:
                            print('第一次收到私聊消息,用户还未点击过私聊按钮'
                                  )  #既未创建对应用户窗体类,又未创建对应用户消息类
                            show_tips(
                                self.display_info, self.pre_time_(),
                                '收到用户:{0}一条私聊消息(如需回复,选中用户点击私聊): '.format(
                                    sender), '').show()
                            # self.chat_historydata[tuple(sender)] = self.private_message[tuple(sender)]
                            self.chat_historydata[tuple(sender)] = []
                            # for msg in self.private_message[tuple(sender)]:
                            self.chat_historydata[tuple(sender)].append(
                                '{0}'.format(self.pre_time_()))
                            self.chat_historydata[tuple(sender)].append(
                                '用户:{0}:{1}'.format(sender, message))
                            self.chat_historydata[tuple(sender)].append('')
                            # print(self.chat_historydata[tuple(sender)])

                if (len(receive_message) == 2):
                    sender = receive_message['sender']
                    message = receive_message['message']
                    if (sender == '服务器'):
                        show_tips(self.display_info, self.pre_time_(),
                                  '{0}: {1}'.format(sender,
                                                    message), '').show()
                    else:
                        show_tips(self.display_info, self.pre_time_(),
                                  '用户: {0}: {1}'.format(sender,
                                                        message), '').show()
                if (len(receive_message) == 1):
                    users = receive_message['users']
                    if (len(self.userlist) <= len(users)):
                        #每次有新加入用户就将他加入到用户列表中,并且更新userlist
                        new_users = [
                            u for u in users if u not in self.userlist
                        ]
                        for user in new_users:
                            if (tuple(user) == self.connection.getsockname()):
                                self.user_info.insert('end',
                                                      '我 :{0}'.format(user))
                            else:
                                self.user_info.insert('end',
                                                      '用户 :{0}'.format(user))
                        self.ord_userlist = self.userlist
                        self.userlist = users
                    if (len(self.userlist) >= len(users)):
                        # 每次有离线用户时在用户列表中删除离线用户,并且更新userlist
                        logout_users = [
                            u for u in self.userlist if u not in users
                        ]
                        for user in logout_users:
                            self.user_info.delete(
                                self.userlist.index(user) + 1)
                        self.ord_userlist = self.userlist
                        self.userlist = users

        except Exception as e:
            show_tips(self.display_info, self.pre_time_(), '连接服务器失败,请重试',
                      '').show()
            self.user_info.delete(1, tkinter.END)
            print(e)