《智谱 AI 聊天应用的开发与实现》
在当今数字化时代,即时通讯和智能交互技术的发展日新月异。本文将详细介绍一个基于 Python 的智能 AI2.0 聊天应用的代码实现,该应用包含客户端和服务器端,为用户提供了一个便捷的聊天交流平台,并融入了智能 AI 助手的功能。
一、应用概述
这个智能 AI2.0 聊天应用旨在实现用户之间的实时聊天,并借助 AI 技术提供智能回复和交互。用户可以通过客户端加入和离开聊天室,发送和接收消息,同时服务器端负责管理客户端连接、转发消息以及与 AI 助手进行交互。
二、客户端代码解析
(一)界面设计与初始化
窗口设置
使用wxPython库创建一个名为 “智能 AI2.0 聊天客户端” 的窗口,设置窗口大小为(480, 700)。
通过设置窗口和面板的背景色,营造出舒适的视觉效果。整体背景色为更淡的灰色(wx.Colour(245, 245, 245)),面板背景色为白色(wx.Colour(255, 255, 255))。
按钮创建
创建了多个按钮,包括 “加入聊天室”(淡绿色按钮wx.Colour(144, 238, 144))、“离开聊天室”(淡粉色按钮wx.Colour(255, 192, 203))、“清空”(淡黄色按钮wx.Colour(255, 255, 153))和 “发送”(淡蓝色按钮wx.Colour(173, 216, 230))按钮。每个按钮都设置了相应的字体和颜色,使其在界面上清晰可辨且美观。
文本框设置
有两个文本框,一个是聊天记录文本框self.chat_text,用于显示聊天记录,设置为多行只读模式(wx.TE_MULTILINE | wx.TE_READONLY)。另一个是输入文本框self.input_text,用于用户输入消息,设置为多行模式(wx.TE_MULTILINE)。
(二)事件绑定
按钮事件
分别为每个按钮绑定了相应的事件处理函数。例如,点击 “加入聊天室” 按钮会调用join_chat函数,点击 “离开聊天室” 按钮会调用leave_chat函数等。
回车键事件
为输入文本框绑定了回车键事件wx.EVT_KEY_DOWN。当用户按下回车键时,如果没有同时按下 Ctrl 键,则调用send_message函数发送消息;如果同时按下 Ctrl 键,则在输入文本框中换行。
(三)聊天功能实现
加入聊天室
在join_chat函数中,当用户点击 “加入聊天室” 按钮且未连接时,尝试连接到服务器(127.0.0.1:8999)。首先将用户的随机生成的名字(通过Faker库生成)发送给服务器进行注册,然后启动一个新线程receive_data来接收服务器端发送的数据,并在连接成功后显示提示信息。如果连接失败,则弹出错误提示框。
接收数据
receive_data函数在一个独立的线程中运行,不断接收服务器发送的数据。接收到数据后,根据数据的编码格式(可能是utf-8或GBK)进行解码。如果消息以 “【系统消息】” 或 “【AI2.0 助手】” 开头,则直接将消息添加到聊天记录文本框;如果不是,则以 “【AI 小秘】” 开头添加到聊天记录文本框。
离开聊天室
leave_chat函数在用户点击 “离开聊天室” 按钮时被调用。如果已连接,向服务器发送 “断开连接” 消息,然后设置连接状态为False,并显示离开聊天室的提示信息。如果发送断开连接消息失败,则弹出错误提示框。
清空聊天记录
clear_chat函数在用户点击 “清空” 按钮时,清空聊天记录文本框的内容。
发送消息
send_message函数在用户点击 “发送” 按钮或按下回车键(未按下 Ctrl 键)时被调用。如果已连接,将用户输入的消息发送给服务器,然后将消息以 “【我】” 开头添加到聊天记录文本框,并清空输入文本框。如果发送消息失败,则弹出错误提示框。
三、服务器端代码解析
(一)界面设计与初始化
窗口设置
创建一个名为 “智能 AI2.0 聊天服务器” 的窗口,设置窗口大小为(500, 650),并设置整体和面板的背景色与客户端类似,以保持风格一致。
按钮创建
有 “启动服务器”(淡绿色按钮)和 “保存聊天记录”(淡蓝色按钮)两个按钮。“启动服务器” 按钮用于启动服务器监听客户端连接,“保存聊天记录” 按钮用于将聊天记录保存到文件中。
文本框设置
聊天记录文本框self.chat_text用于显示服务器端的聊天记录,设置为多行只读模式。
(二)事件绑定
为 “启动服务器” 按钮绑定start_server函数,为 “保存聊天记录” 按钮绑定save_chat_record函数。
(三)服务器功能实现
启动服务器
在start_server函数中,当点击 “启动服务器” 按钮且服务器未运行时,尝试绑定服务器端口(0.0.0.0:8999)并开始监听。启动一个新线程server_loop来处理客户端连接请求。如果启动成功,显示提示信息;如果失败,则弹出错误提示框。
服务器循环
server_loop函数在一个独立的线程中运行,不断接受客户端连接。当有客户端连接时,接收客户端发送的用户名,创建一个ClientHandler线程来处理该客户端的通信,并将客户端线程添加到client_threads字典中进行管理。同时,向所有客户端发送欢迎消息,并调用send_message函数将消息发送给 AI 助手获取回复并转发给客户端。
发送消息
send_message函数将消息添加到服务器端的聊天记录文本框,并通过ThreadPoolExecutor并发地向所有在线客户端发送消息。同时,将用户发送的消息传递给 AI 助手获取回复,并将回复发送给客户端,同时将 AI 助手的回复也添加到聊天记录文本框中。
保存聊天记录
save_chat_record函数在用户点击 “保存聊天记录” 按钮时被调用。它获取聊天记录文本框的内容,将其写入到record.log文件中。如果保存成功,显示提示信息;如果失败,则弹出错误提示框。
(四)客户端处理线程
客户端处理器类
ClientHandler类继承自threading.Thread,用于处理单个客户端的通信。在初始化时,接收客户端套接字、用户名和服务器实例。
运行方法
run方法在一个独立的线程中运行,不断接收客户端发送的消息。如果接收到的消息是 “断开连接”,则设置客户端线程的运行状态为False,并向其他客户端发送该用户离开的消息。如果接收到其他消息,则将消息转发给服务器的send_message函数进行处理。当出现接收消息错误时,设置运行状态为False。最后,尝试关闭客户端套接字。
代码展示:
from zhipuai import ZhipuAI
class ZhipuAIChat:
def __init__(self, api_key):
self.name = "AI小秘"
self.client = ZhipuAI(api_key=api_key)
def get_response(self, question):
messages = [
{
"role": "user", "content": question}
]
response = self.client.chat.completions.create(
model="glm-4-flash",
messages=messages
)
try:
return response.choices[0].message.content
except AttributeError:
return "无法获取回答"
这里我是把调用API接口封装成了一个类一别创建对象。
import wx
from socket import *
import threading
from concurrent.futures import ThreadPoolExecutor
import ai_test
# 创建 AI2.0 聊天实例
ai_chat = ai_test.ZhipuAIChat('*************************')#这里填写自己的key
class ServerApp(wx.Frame):
def __init__(self):
# 设置窗口标题为“智能 AI2.0 聊天服务器”
super().__init__(None, title='智能 AI2.0 聊天服务器', size=(500, 650))
self.is_running = False
self.server_socket = socket()
self.server_socket.bind(('0.0.0.0', 8999))
self.server_socket.listen(5)
self.client_threads = {
}
self.pool = ThreadPoolExecutor(max_workers=10)
self.SetBackgroundColour(wx.Colour(245, 245, 245)) # 整体背景色设置为更淡的灰色
# 创建面板并设置布局管理器
self.panel = wx.Panel(self)
self.panel.SetBackgroundColour(wx.Colour(255, 255, 255)) # 面板背景色设置为白色
sizer = wx.BoxSizer(wx.VERTICAL)
# 创建启动服务器按钮
self.start_server_btn = wx.Button(self.panel, label='启动服务器')
self.start_server_btn.SetBackgroundColour(wx.Colour(144, 238, 144)) # 淡绿色按钮
self.start_server_btn.SetForegroundColour(wx.Colour(0, 0, 0))
self.start_server_btn.SetFont(wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
sizer.Add(self.start_server_btn, 0, wx.EXPAND | wx.ALL, 5)
# 创建保存聊天记录按钮
self