要在微信小程序实现聊天对话功能,回话是流式应答,这里使用了WebSocket技术。WebSocket大家应该都很熟悉,使用wx.connectSocket就可以了。这里可能需要注意下的是流式应答,后端如何发送,前端如何接收。直接上代码:
可以扫码体验:

后端关键代码:
- // 定义正则表达式
- String regex = "data:\\s*(\\{.*\\})";
- // 创建Pattern对象
- Pattern pattern = Pattern.compile(regex);
-
- String line;
- while ((line = reader.readLine()) != null) {
- // 处理每条数据
- // System.out.println(line);
- // 创建Matcher对象
- Matcher matcher = pattern.matcher(line);
- // 查找匹配项
- if (matcher.find()) {
- String dataValue = matcher.group(1);
- JSONObject jsonObject = JSON.parseObject(dataValue);
-
- String content = jsonObject.getString("result");
- Boolean end = jsonObject.getBoolean("is_end");
-
- JSONObject data = new JSONObject();
- data.put("content", content);
- data.put("end", end);
- data.put("type", "message");
- webSocketServer.sendInfo(uid.toString(), data.toJSONString());
- }
- }
小程序ts代码:
- data: {
- messages: [], // 聊天消息列表
- inputValue: '', // 输入框的值
- ask: '', // 输入框的值
- socketOpen: false, // WebSocket 连接状态
- socketTask: null, // WebSocket 实例
- answering: false, // 回答中。。。
- type: 2,
- credit: 0,
- scrollTop: 0,
- }
- scrollToBottom() {
- // 在需要滚动到最底部的时机
- const query = wx.createSelectorQuery();
- query.select('.chat-container').boundingClientRect();
- query.select('.msgList').boundingClientRect();
- query.exec(res => {
- const scorllHeight = res[0].height;
- const listHeight = res[1].height;
-
- this.setData({
- scrollTop: listHeight - scorllHeight + 92
- });
- });
- },
- async onLoad() {
- const chatList = 历史聊天记录;
- const chatListMessage: any = [];
- if (chatList && chatList.length > 0) {
- chatList.map((v: any) => {
- const ask = {
- sender: 'user',
- avatar: '',
- content: v.ask,
- createTime: v.createTime,
- id: v.id,
- };
- const answer = {
- sender: 'chat',
- avatar: 'xxx',
- content: v.answer,
- id: v.id,
- }
- chatListMessage.push(ask);
- chatListMessage.push(answer);
- })
- }
- // 初始化聊天消息列表,包含一条欢迎消息
- const messages: any = [
- {
- sender: 'chat',
- avatar: 'xxx',
- content: `欢迎`
- },
- ...this.data.messages,
- ...chatListMessage
- ]
- // @ts-ignore
- this.setData({ messages });
- this.scrollToBottom();
- },
- //滾動到底部
- bindscroll() {
- // console.log(1);
- },
- onUnload: function () {
- // 页面卸载时关闭 WebSocket 连接
- this.closeSocket();
- },
-
- inputChange: function (e: any) {
- // 监听输入框值的变化
- this.setData({
- inputValue: e.detail.value
- });
- },
-
- async sendMessage() {
- // 发送消息
- const message = this.data.inputValue;
- if (message.trim() === '') {
- showToast("请输入问题");
- return;
- }
-
-
-
- // 添加用户发送的消息到聊天消息列表
- const newMessage = {
- sender: 'user',
- avatar: '',
- content: message
- };
- //@ts-ignore
- this.data.messages.push(newMessage);
-
- // 清空输入框
- this.setData({
- messages: this.data.messages,
- inputValue: '',
- });
-
- this.data.ask = message;
- // 发送消息到 Chat
- this.sendToChat(message);
- },
-
- sendToChat: function (message: any) {
- if (!this.data.socketOpen) {
- // 如果 WebSocket 连接未打开,则创建连接
- this.createSocket();
- }
- this.setData({ answering: true });
-
- // 这里请求后台
-
- // 处理 Chat 的回答消息
- const newMessage: any = {
- sender: 'chat',
- avatar: '',
- content: ""
- };
- //@ts-ignore
- this.data.messages.push(newMessage);
- // 更新聊天消息列表并滚动到最新消息
- this.setData({ messages: this.data.messages });
- this.scrollToBottom();
- },
-
- createSocket: function () {
- // 创建 WebSocket 连接
- const socketTask = wx.connectSocket({
- url: ``, // 替换为你的 WebSocket 服务器地址
- success: () => {
- console.log('WebSocket 连接成功');
- },
- fail: (error) => {
- console.error('WebSocket 连接失败', error);
- }
- });
-
- // 监听 WebSocket 连接打开事件
- socketTask.onOpen(() => {
- console.log('WebSocket 连接已打开');
- this.setData({
- socketOpen: true,
- socketTask: socketTask
- });
- });
-
- // 监听 WebSocket 接收到服务器的消息事件
- socketTask.onMessage((res: any) => {
- const data = JSON.parse(res.data);
- // console.log(data);
- if (data.type === 'message') {
- // 收到 Chat 的回答消息
- this.handleChatResponse(data);
- }
- });
-
- // 监听 WebSocket 连接关闭事件
- socketTask.onClose(() => {
- console.log('WebSocket 连接已关闭');
- this.setData({
- socketOpen: false,
- socketTask: null
- });
- });
-
- // 监听 WebSocket 错误事件
- socketTask.onError((error) => {
- console.error('WebSocket 错误', error);
- });
- },
-
- closeSocket: function () {
- if (this.data.socketOpen) {
- // 关闭 WebSocket 连接
- this.data.socketTask.close();
- }
- },
-
- handleChatResponse: async function (data: any) {
-
- // 处理 Chat 的回答消息
- const index = this.data.messages.length - 1;
- this.data.messages[index].content += data.content;
- // 更新聊天消息列表并滚动到最新消息
- this.setData({ messages: this.data.messages });
-
- if (data.end) {
- this.setData({ answering: false, messages: this.data.messages });
- this.data.ask = "";
- };
-
- this.scrollToBottom();
- },
可以扫码体验: