springboot + vue + websocket + ECharts

初衷

因为刚接触VUE的前端开发,自己也是做起来也是模模糊糊的。遇到的一些坑记录一下

缘由

在完成一个页面展示的折线图时,虽然每次刷新都是直接从后端直接拿最新的数据,但是会导致界面的整体刷新,就想做一个异步的刷新,让折线图能像股市看板一样的存在,线是能实时变化的。思考了一下有两种解决方案

  1. 在前端JS中设置一个定时器,每秒往后端请求一次(这种感觉太耗资源了,尤其有时候需要看日志,控制台打印出来的东西根本看不了,所以直接放弃了这种)
  2. 使用websocket通讯,保证一个长连接,后端主动像前端推送消息(从被动的被访问变成主动,当需要时才给前端数据)

后端Springboot实现

1.创建一个配置文件完成websocket的启动


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;


/**
 * 
 * @author 解咚咚
 * @date 创建时间2019年6月25日上午10:04:54
 * @version 1.0
 */
@Configuration
public class myWebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

}

2.之后可以完成和前端建立连接的一些功能了


import java.io.IOException;
import java.util.List;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import org.fh.entity.PageData;
import org.java_websocket.server.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.chaintWMS.mapper.HomePageMapper;
import com.chaintWMS.utils.Result;

/**
 * 
 * @author 解咚咚
 * @date 创建时间2019年6月25日上午10:26:59
 * @version 1.0
 */
@ServerEndpoint(value = "/websocket")  //这里是前端访问地址时需要带的。
@Component
public class MyWebsocket {

	private static HomePageMapper homePageMapper;    
	// 注入的时候,给类的 service 注入
    @Autowired
    public void setChatService(HomePageMapper homePageMapper) {
    	MyWebsocket.homePageMapper = homePageMapper;
    }
	//上面这么写的原因是因为直接用   @Autowired注入会导致 homePageMapper未null 注入不成功,所以需要这么去写。具体原因可去百度其他文档
	//其实这里还可以  写一个连接数的静态变量,当每次连接成功后 ++一次,断开连接时 -- 一次,可以实时观测连接数,根据具体需求去做就可以了
	//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
	private static CopyOnWriteArraySet<MyWebsocket> webSocketSet = new CopyOnWriteArraySet<MyWebsocket>();
	 
    //private volatile static List<Session> sessions = Collections.synchronizedList(new ArrayList());
	private Session session;
    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        webSocketSet.add(this);      //将连接添加到安全的线池去
    	System.out.println("连接成功");
        
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        System.out.println("有一连接关闭");
    }

    /**
     * 给前台推消息
     * @param session
     * @param rs
     * @throws IOException
     */
    public void sendMessage(String rs) throws IOException {
    	if(this.session.isOpen()) {   //判断session是否是打开状态的,打开状态的才发。
    		this.session.getBasicRemote().sendText(rs);
    	}
    }
    //下面这个方法是对外提供的静态方法,当业务层需要给改变前端显示内容,或给前端推送内容时调用此方法(可根据具体业务逻辑更改此方法)
    public static void sendInfo(String message) throws IOException {
    	List<PageData> hhlist = homePageMapper.gethhData();
    	String json = Result.of(200,"得到实时数据成功").put("hhlist", hhlist).json();
    	if(message.equals("1")) {
    		for (MyWebsocket item : webSocketSet) {   //这是默认给全部的连接发送消息   如果不需要给全部发,可以定义一个变量来区别每次链接的ID 给对应的ID发
        		item.sendMessage(json);
        	}
    	}
    }
    
    /**
     * 收到前端客户端消息后调用的方方法
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("来自客户端的消息:" + message);
    }

    /**
     * 发生异常时调用
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生异常");
        error.printStackTrace();
    }


}

前端VUE的实现

1.在 methods里创建一个初始化websocket的函数

initWebSocket(){ //初始化weosocket
        const $vm = this
        let ws = new WebSocket('ws://10.113.5.246:8080/chaintWMS/websocket');  //这里new 一个WebSocket对象将连接地址传入(这个连接地址很重要,很多情况连接不上就是连接地址没用写对)
         ws.onopen = () => {
          // Web Socket 已连接上,使用 send() 方法发送数据
          console.log('发送数据中。。。')
          ws.send('你好')
          console.log('数据发送完成。')
        }
        ws.onmessage = evt => {    //后端发来的消息接收(注意数据放在evt的data中并且是个JSON字符串,需要parse成JSON对象去使用)
          let hhlist = JSON.parse(evt.data);

 //具体业务逻辑
 
		 $vm.$set($vm.panelData,"rsumhh",psu) //这里是 vue给一些已经改变了的图表数据后,显示内容没用变化时用的。(直接用=去赋值界面的显示是不会变的 Echarts 图表就是需要用 set去改变值的变化)
          console.log('数据已接收...')

        }
        ws.onclose = function () {
          // 关闭 websocket
          console.log('连接已关闭...')
        }
        // 路由跳转时结束websocket链接
        this.$router.afterEach(function () {
          ws.close()
        })
    }

2.然后在created()中添加方法的调用

 created() {
      //页面刚进入时开启长连接
      this.initWebSocket()
  },

Echart动态拿数据时不显示原因(加载顺序问题)

1.需要在后端拿数据时,进行异步时,需要在拿完数据之后 在调用 this.initChart() 初始化的方法(在去加载图表信息)

getWarehouseInventory() {
      const $vm = this
      getWarehouseInventory().then(res => {
        if (res.code === 200) {
          for (var i in res.warehouseinventory) {
            $vm.xvalue.push(res.warehouseinventory[i].WarehouseCode)
            // $vm.wnvalue.push(res.warehouseinventory[i].netweight)
            $vm.wavalue.push(res.warehouseinventory[i].Amount)
          }
          this.initChart()   //ECharts的具体实现方法
        }
      })
    }

结语

第一次写,感觉很多没用表达清楚,也就记录一下自己在开发中遇到的一些坑吧。这此的坑主要就是 VUE的赋值机制问题,直接使用 =等于去赋值并不会改变显示的值,需要用 set 去改变,还有当Echart加载时顺序的问题

  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
# 项目特点 - 前台参考"Hexo"的"Butterfly"设计,美观简洁,响应式体验好。 - 后台参考"element-admin"设计,侧边栏,历史标签,面包屑自动生成。 - 采用Markdown编辑器,写法简单。 - 评论支持表情、GIF动图输入回复等,样式参考Valine。 - 前后端分离部署,适应当前潮流。 - 接入第三方登录,减少注册成本。 - 留言采用弹幕墙,更加炫酷。 - 支持代码高亮和复制,图片预览,深色模式等功能,提升用户体验。 - 搜索文章支持高亮分词,响应速度快。 - 新增文章目录、推荐文章等功能,优化用户体验。 - 新增在线聊天室,支持撤回、语音输入、统计未读数量等功能。 - 新增aop注解实现操作日志功能。 - 支持动态权限修改,采用RBAC模型,前端菜单和后台权限实时更新。 - 后台管理支持修改背景图片,博客配置等信息,操作简单,支持上传相册。 - 代码支持多种搜索模式(Elasticsearch或MYSQL),支持多种上传模式(OSS或本地),可支持配置。Elasticsearch占内存较高,如果服务器配置太低,不建议使用。 - 新增网站导航功能,页面优雅美观。可自行添加自己常用的网站进行分类和排序。 - 新增聊天管理功能,方便清理垃圾聊天内容。 - 新增登录日志功能,随时查看用户的登录信息。 - 前台页面重新布局重构,页面布局更加简洁,首页加载速度更快。 - 前台首页文章列表顶部新增滚动消息,超级炫酷。 - 新增了监控用户是否授权的功能、增加了用户的体验性。 - 增加图片删除后也将该路径的图片删除的功能、大大提高了文件存储的利用率。 - 将接口进行**axios**二次封装、更利于接口的请求和响应。 - 新增本博客配套的**微信小程序**,可随时用手机浏览文章。并且接入微信登录,减少注册成本。 - **微信小程序**新增每日新闻热搜功能、可随时查看热搜。 - 新增本博客配套的**App**,同时接入qq、微博登录,使用更加方便。 - 代码遵循阿里巴巴开发规范,利于开发者学习。 ## 技术介绍 **前端:** vue + vuex + vue-router + axios + vuetify + element + echarts + uniapp + uview + Html + Css + JavaScript **后端:** SpringBoot + nginx + docker + SpringSecurity + Swagger2 + MyBatisPlus + Mysql + Redis + elasticsearch + RabbitMQ + MaxWell + Websocket **其他:** 接入QQ,微博、微信第三方登录,接入腾讯云人机验证、websocket ## 运行环境 ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值