文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

微信小程序 | 基于小程序+Java+WebSocket实现实时聊天功能

2023-09-06 18:34

关注

一、文章前言

此文主要实现在小程序内聊天对话功能,使用Java作为后端语言进行支持,界面友好,开发简单。

二、开发流程及工具准备

2.1、注册微信公众平台账号。
2.2、下载安装IntelliJ IDEA(后端语言开发工具),Mysql数据库,微信Web开发者工具。

三、开发步骤

1.创建maven project

先创建一个名为SpringBootDemo的项目,选择【New Project】
在这里插入图片描述

然后在弹出的下图窗口中,选择左侧菜单的【New Project】(注:和2022之前的idea版本不同,这里左侧没有【Maven】选项,不要选【Maven Archetype】!!!),输入Name(项目名):SpringBootDemo,language选择【java】,build system选择【maven】,然后选择jdk,我这里选的是jdk18.

在这里插入图片描述然后点击【Create】
在这里插入图片描述

2.在project下创建module

点击右键选择【new】—【Module…】
在这里插入图片描述
左侧选择【Spring initializr】,通过idea中集成的Spring initializr工具进行spring boot项目的快速创建。窗口右侧:name可根据自己喜好设置,group和artifact和上面一样的规则,其他选项保持默认值即可,【next】
在这里插入图片描述

Developer Tools模块勾选【Spring Boot DevTools】,web模块勾选【Spring Web】

在这里插入图片描述

此时,一个Springboot项目已经搭建完成,可开发后续功能

3.编写一个消息实体类、Mapper、service(三层架构)

@Datapublic class Chat {    @TableId(type = IdType.AUTO)    private Long id;    private Long userId;    private Long targetUserId;    private LocalDateTime createTime;    private String userName;    private String targetUserName;    private String content;}

由于我们使用mybatis-plus,所以简单的增删改查不用自己写,框架自带了,只需要实现或者继承他的Mapper、Service
在这里插入图片描述在这里插入图片描述

4.编写WebSocket服务类

@ServerEndpoint("/imserver/{userId}")@Componentpublic class WebSocketService {        private static ConcurrentHashMap<String, WebSocketService> webSocketMap = new ConcurrentHashMap<>();        private Session session;        private String userId = "";    public static ChatMapper chatMapper = null;        @OnOpen    public void onOpen(Session session, @PathParam("userId") String userId) {        this.session = session;        this.userId = userId;        if (webSocketMap.containsKey(userId)) {            webSocketMap.remove(userId);            webSocketMap.put(userId, this);            //加入set中        } else {            webSocketMap.put(userId, this);            //加入set中        }    }        @OnError    public void onError(Session session, Throwable error) {        error.printStackTrace();    }        public void sendMessage(String message) {        try {            this.session.getBasicRemote().sendText(message);        } catch (IOException e) {            e.printStackTrace();        }    }        public static void sendInfo(Chat chat) {        QueryWrapper<Chat> queryWrapper = new QueryWrapper();        List<Chat> chats=chatMapper.selectList(queryWrapper.lambda()                .eq(Chat::getTargetUserId, chat.getTargetUserId()).or().eq(Chat::getUserId, chat.getTargetUserId()).or().eq(Chat::getTargetUserId, chat.getUserId()).or().eq(Chat::getUserId, chat.getUserId()));        //log.info("发送消息到:"+userId+",报文:"+message);        if (!StringUtils.isEmpty(chat.getTargetUserId().toString()) && webSocketMap.containsKey(chat.getTargetUserId().toString())) {            webSocketMap.get(chat.getUserId().toString()).sendMessage(JSONObject.toJSONString(chats));            webSocketMap.get(chat.getTargetUserId().toString()).sendMessage(JSONObject.toJSONString(chats));        } else {            webSocketMap.get(chat.getUserId().toString()).sendMessage(JSONObject.toJSONString(chats));        }    }        public static void close(String userId) {        if (webSocketMap.containsKey(userId)) {            webSocketMap.remove(userId);        }    }        public static Map getOnlineUser() {        return webSocketMap;    }

5.创建控制器Controller

先创建Controller Package
在这里插入图片描述

创建一个Controller
在这里插入图片描述
输入类名,选在【Class】
在这里插入图片描述

因为要编写Rest风格的Api,要在Controller上标注@RestController注解

创建具体的Api接口

@RestControllerpublic class DemoController {    @Autowired    private ChatService chatService;    @PostMapping("/push")    public ResponseEntity<String> pushToWeb(@RequestBody Chat chat) throws IOException {        chat.setCreateTime(LocalDateTime.now());        chatService.save(chat);        WebSocketService.sendInfo(chat);        return ResponseEntity.ok("MSG SEND SUCCESS");    }    @GetMapping("/close")    public String close(String userId) {        WebSocketService.close(userId);        return "ok";    }    @GetMapping("/getOnlineUser")    public Map getOnlineUser() {        return WebSocketService.getOnlineUser();    }    @GetMapping("/getMessage")    public ResponseEntity<List<Chat>> getMessage(String userId) {        QueryWrapper<Chat> queryWrapper = new QueryWrapper();        List<Chat> list = chatService.                list(queryWrapper.lambda().eq(Chat::getTargetUserId, userId).or().eq(Chat::getUserId, userId));        return ResponseEntity.ok(list);    }}

小程序代码
在这里插入图片描述
3.20、在pages文件夹下面创建一个文件夹并新建对应的page文件,并实现聊天对话框样式。
在这里插入图片描述

在这里插入图片描述

<view class="cu-chat" id="j_page">  <view class="cu-item 'self'" wx:for="{{chatData}}">    <view class="main">      <view class="content shadow bg-green">        <text>{{item.content}}</text>      </view>    </view>    <view class="cu-avatar radius" style="background-image:url(../../../images/cat.jpg)"></view>    <view class="date">{{item.createTime}}</view>  </view></view><view class="cu-bar foot input {{InputBottom!=0?'cur':''}}" style="bottom:{{InputBottom}}px">  <view class="action">    <text class="cuIcon-sound text-grey"></text>  </view>  <input class="solid-bottom" value="{{content}}" bindinput="formMsg"  bindfocus="InputFocus" bindblur="InputBlur" adjust-position="{{false}}" focus="{{false}}" maxlength="300" cursor-spacing="10"></input>  <view class="action">    <text class="cuIcon-emojifill text-grey"></text>  </view>  <button class="cu-btn bg-green shadow" bindtap="sendMsg">发送</button></view>
.cu-chat {display: flex;flex-direction: column;}.cu-chat .cu-item {display: flex;padding: 30rpx 30rpx 70rpx;position: relative;}.cu-chat .cu-item>.cu-avatar {width: 80rpx;height: 80rpx;}.cu-chat .cu-item>.main {max-width: calc(100% - 260rpx);margin: 0 40rpx;display: flex;align-items: center;}.cu-chat .cu-item>image {height: 320rpx;}.cu-chat .cu-item>.main .content {padding: 20rpx;border-radius: 6rpx;display: inline-flex;max-width: 100%;align-items: center;font-size: 30rpx;position: relative;min-height: 80rpx;line-height: 40rpx;text-align: left;}.cu-chat .cu-item>.main .content:not([class*="bg-"]) {background-color: var(--white);color: var(--black);}.cu-chat .cu-item .date {position: absolute;font-size: 24rpx;color: var(--grey);width: calc(100% - 320rpx);bottom: 20rpx;left: 160rpx;}.cu-chat .cu-item .action {padding: 0 30rpx;display: flex;align-items: center;}.cu-chat .cu-item>.main .content::after {content: "";top: 27rpx;transform: rotate(45deg);position: absolute;z-index: 100;display: inline-block;overflow: hidden;width: 24rpx;height: 24rpx;left: -12rpx;right: initial;background-color: inherit;}.cu-chat .cu-item.self>.main .content::after {left: auto;right: -12rpx;}

3.21、在JS中实现请求聊天列表及新增聊天信息的接口,使用websocket进行实时刷新聊天功能,提供onOpen、onClose、onError、onMessage方法。

var socket = null;Page({  data: {    InputBottom: 0,    chatData: [],    content: '', //需要发送的内容    userId: 2,  },  onLoad() {    let that = this;    socket = wx.connectSocket({      url: 'ws://localhost:8080/imserver/2',      success: res => {          console.info('创建连接成功');          //socketTaskId: 22          // console.info(res);      }  });  // console.info(socket);  //事件监听  socket.onOpen(function () {      console.info('连接打开成功');  });  socket.onClose(function () {      console.info('连接关闭成功');  });  socket.onError(function () {      console.info('连接报错');  });  //服务器发送监听  socket.onMessage(function (e) {    console.info(e.data);    var list=JSON.parse(e.data);        that.setData({chatData:list});  });      wx.request({        url: 'http://localhost:8080/getMessage?userId=2',        method: 'get',        dataType: "json",        success: function (res) {          that.setData({            chatData: res.data          });        }      });      wx.pageScrollTo({        scrollTop: 9999      })  },  InputFocus(e) {    this.setData({      InputBottom: e.detail.height    })  },  formMsg(e) {    this.setData({      content: e.detail.value.trim()    })  },  //发送消息  sendMsg() {    let that = this;    let info = {      userName: '李四',      content: that.data.content,      userId: 2,      targetUserId: 1,      targetUserName: "张三"    };    wx.request({      url: 'http://localhost:8080/push',      data: JSON.stringify(info),      method: 'post',      contentType:"application/json",      dataType: "json",      success: function (identify) {        that.setData({          content: '',        });        //发送消息后             wx.pageScrollTo({          scrollTop: 9999        })      }    });  },  InputBlur(e) {    this.setData({      InputBottom: 0    })  }})//查询消息列表function selectMsg() {  let that = this;};

3.22、准备两张头像,在WXML中根据对应的用户名判断聊天记录是否是自己发出,并赋对应的class样式,后续这个步骤可以直接在接口返回的数据中进行判断,请求查询列表的接口将用户token作为参数传输过去即可。

<view class="cu-chat" id="j_page">  <view class="cu-item {{item.userId=='2'?'self':''}}" wx:for="{{chatData}}">    <view class="cu-avatar radius" style="background-image:url(../../../images/cat.jpg)" wx:if="{{item.userId=='1'}}"></view>    <view class="main">      <view class="content shadow {{item.userId=='1'?'bg-green':''}}">        <text>{{item.content}}</text>      </view>    </view>    <view class="cu-avatar radius" style="background-image:url(../../../images/dog.jpg)" wx:if="{{item.userId=='2'}}"></view>    <view class="date">{{item.createTime}}</view>  </view></view> 

3.23、请求聊天记录的接口和新增聊天信息的接口都跑通后,我们将现有小程序复制一份,在复制出的这份小程序中的JS将用户名改为张三、李四,然后发送消息。这里需要注意的是,我们需要在每次发送消息后将页面内容定位在底部,一直保持一个阅读最新消息的状态。

wx.pageScrollTo({  scrollTop: 9999})

这里采用的一个比较简单的方式实现的聊天功能,用到了ws长连接的方式来实现这个功能,完成后源码会以资源的形式上传提供给大家。

来源地址:https://blog.csdn.net/wml_JavaKill/article/details/127807331

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯