欢迎大家来体验,WeChat搜●索《计分记账神器》
前言
作为一个程序员,我相信大家都有这么一个愿望,希望自己做的东西能够得到广泛的应用。也不说能为自己带来多少收入,于是我就抱着试一试的心态。在公司项目不多,事情不急的情况下,开始琢磨能够做点什么东西。
①是想要在自己开发的过程中去学习一些新的东西,把一些不常用的技术或者知识尝试的去用到自己的项目中。
②是想使得空余的时间更加的充实,也不太想沉迷过多于虚拟的世界。
③是想看看自己独立开发起来是否能够应对一些问题。
于是再经过不断的翻阅当今有的小程序中,选到了 《记账工具类目》,相对于普通的记账,我更想做的是能过实时多人在线协同记账的工具。在考虑到开发周期以及推广难度等,因为也临近过年了,想到大部分人聚在一起时,多多少少也会有人喜欢打扑克牌,那也就肯定会进行"计分",然后我就开始着手开发了。
ps:由于本人主要做后端开发,没有专业ui支持界面也是比较普通请见谅。
功能介绍
大致界面展示
目前主要的基础功能如下:
- 个人首页: 修改个人信息、房间列表、创建房间、联系客服。
- 房间列表:房间信息、房间流水(操作日志)、统计(房间分值结算)。
- 房间内置:结算、退出、日志、刷新、编辑、邀请、分享、客服、分值操作。
环境以及上线准备
1、需要有一台自己的服务器,我这里用的是2g2h6m的服务器,在目前用户量不大情况下够用了。
2、购买域名(已有域名www.eztool.top),进行域名备案,申请配置域名安全证书(小程序上线需要使用https)。
3、需要开通一个小程序账号,搜索《微信公众平台》自行操作即可。
4、后续上线小程序也是需要备案的,以及30RMB的个人认证费用。
准备好以上这些小程序就可以开发上线了。最后一点也是需要小程序发布体验版后才可以操作的。
后端技术栈
-
SpringBoot:
- 后端应用层采用主流的 SpringBoot 框架,提供高效的开发和集成能力。
- SpringBoot的特性,如自动配置和简化的开发流程,有助于快速搭建稳健的后端服务。
-
MyBatis-Plus:
- 持久层采用 MyBatis-Plus,简化了 MyBatis 的开发流程,提供便捷的CRUD操作。
- MyBatis-Plus通过其强大的代码生成和查询构建功能,优化了数据持久化层的开发效率。
-
WebSocket:
- 实时通信采用 WebSocket 协议,为用户提供了实时数据同步的能力。
- WebSocket在处理分值加减等实时操作时,确保了数据的及时更新和用户体验的实时性。
-
MySQL:
- 作为主要的关系型数据库,MySQL负责存储关键数据,如用户信息、房间数据等。
- MySQL通过其稳定性和可靠性,为应用提供了数据持久化的支持。
-
Redis:
- Redis被应用于多个方面,包括缓存、分布式锁和防刷机制等。
- 通过Redis的高速缓存和灵活的数据结构,提高了系统的性能和应对高并发的能力。
-
MinIO:
- 自建的MinIO分布式文件存储系统用于存储OSS文件,提供高可用性和可伸缩性。
- MinIO的部署为系统提供了弹性的文件存储解决方案。
-
Nginx:
- Nginx充当反向代理服务器,用于负载均衡和提高系统的可用性。
- 通过Nginx的配置,实现对后端服务的分发和请求转发,优化了系统的稳定性和性能。
前端技术栈
-
Taro:
- Taro 是一款跨端开发框架,用于开发小程序和Web应用。采用一套代码多端运行的策略,简化了前端开发流程。
- 借助 Taro,实现了小程序端和Web端的高效开发和兼容性。
-
Taro UI:
- Taro UI 是基于 Taro 框架开发的组件库,提供了一系列美观、易用的UI组件。
- 在小程序前端中,Taro UI的引入有效简化了界面开发,保障了视觉一致性和用户体验。
-
WebSocket:
- WebSocket 是一种用于在客户端和服务器之间进行实时通信的协议。
- 在小程序中,WebSocket被用于实现实时通信,特别是在处理用户分值操作时的实时同步。
功能实现相关
实时协同操作——WebSocket通信
在之前做的项目中,也没有相关websocket的开发经验,后面也是慢慢从一些相关的技术文章开始了解的。以下我也是大致的说明一下,以及大致实现。
WebSocket是什么?
WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。
WebSocket特点
- 1、建立在 TCP 协议之上,服务器端的实现比较容易。
- 2、与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
- 3、数据格式比较轻量,性能开销小,通信高效。
- 4、可以发送文本,也可以发送二进制数据。
- 5、没有同源限制,客户端可以与任意服务器通信。
- 6、协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。
具体实现
引入maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
配置类
@Component
public class SocketConfig {
/**
* 会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint
* 要注意,如果使用独立的servlet容器,
* 而不是直接使用springboot的内置容器,
* 就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
socket连接代码实现 需要加上@ServerEndpoint() 注解
以下是后端接收socket连接的主要逻辑,这里抽象了一个实现类,具体业务实现逻辑都在SocketService中实现,这样连接的类就会简洁一些,代码我就不贴了比较长,感兴趣的可以私聊沟通。
@Slf4j
@ServerEndpoint("/roomLink/{userData}")
@Component
public class WebSocketServer {
private static SocketService socketService;
/**
* 由于@ServerEndpoint 是连接时才会创建对象,而StringRedisTemplate 是在容器启动的时候注入的,每次新连接后就会不注入,所以加入此方法
* @param socketService
*/
@Autowired
private void setSocketService(SocketService socketService){
WebSocketServer.socketService= socketService;
}
//建立连接成功调用
@OnOpen
public void onOpen(Session session, @PathParam(value = "userData") String userData){
socketService.onOpen(session,userData);
}
//关闭连接时调用
@OnClose
public void onClose(@PathParam(value = "userData") String userData){
socketService.onClose(userData);
}
//收到客户端信息
@OnMessage
public void onMessage(String message) {
socketService.onMessage(message);
}
//错误时调用
@OnError
public void onError(Session session, Throwable throwable){
socketService.onError(session,throwable);
}
}
WebSocket也就是实时协同操作的核心原理了
在开发以及测试的过程中发现 小程序在和服务端建立长连接的时候,时不时会中断连接,有时候三分钟,有时候十分钟,就是不固定的随机时长中断。然后还是决定上了"心跳"机制,小程序这边每隔一段时间就会通过socket发送一条心跳信息,服务端这边也会响应一个消息,表示接收成功。一旦这个消息没有接收到一段时间后小程序这边就会触发重新连接。这样一来就保证了这个在线socket断连的问题了。
有一个可以优化的点是,当socket传输的消息较大时,可以使用gzip压缩算法将 消息内容进行压缩,然后在接收的时候再对消息进行解压处理。再本地测试下来后,发现当消息体达到1M以上可以进行一个消息体的压缩,因为消息体过小的时候压缩反而效果不好,还有可能比原来的内容还要大。
这里还需要注意的是,小程序上线后是需要配证书的,普通的请求是要https,而 socket连接这边 普通的ws协议也是不能够使用的,需要使用 wss协议,由于我使用的nginx反向代理,则需要在 nginx中配置,如下。
nginx配置wss代理
# 需要代理到的socket服务器端口
upstream webSocket {
server 127.0.0.1:3333;
}
server {
listen 80;
listen 443 ssl;
server_name localhost www.eztool.top;
index index.php index.html index.htm default.php default.htm default.html;
root /xxx/xxx/xxxx;
#SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则
#error_page 404/404.html;
ssl_certificate /nginx/sslkey/eztool.top_bundle.crt;
ssl_certificate_key /nginx/sslkey/eztool.top.key;
ssl_session_timeout 5m;
#请按照以下协议配置
ssl_protocols TLSv1.2 TLSv1.3;
#请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
# wss 代理配置
location /wss/ {
proxy_pass http://webSocket/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_send_timeout 7200s;
proxy_read_timeout 7200s;
proxy_connect_timeout 7200s;
}
#其他请求代理配置这里就省略了。。。。。。。。
}
结尾
感谢各位亲临阅读,如果您有任何想法或建议,欢迎积极交流。我衷心期待听取您的意见,以不断优化我们的产品。通过互相分享经验和见解,我们将共同成长,提升业务能力,因为作为程序员,持续学习与进步永远是不可或缺的使命。期待与您保持更紧密的沟通,共同推动技术的发展和创新。
感谢您一直阅读至此,愿新的一年,给您带来满满的喜悦和美好。麻烦用您发财的小手点上一个赞吧,谢谢!