springboot+websocket+vue+vuex实现在线聊天(客户端)(代码片段)

Java小许 Java小许     2022-12-31     413

关键词:

一、使用node代理ws请求

proxyObj['/ws'] = 
    ws: true,
    target: "ws://localhost:8081"

导入连接需要连接websocket的js 

npm install sockjs-client
npm install stompjs
npm install sass-loader@8.0.2 --save //这个是css写法需要用到的 不加版本会报错
npm install node-sass@4.14.1 --save //安装sass-loader 需要有node-sass

二、创建聊天窗口

        可以使用一个按钮来跳转到聊天页面 

          <el-button type="text" icon="el-icon-message-solid" style="color: black;margin-right: 5px" @click="goChat" ></el-button>

goChat()
      this.$router.push('/chat');
    

三、聊天页面绘制 (引入第三方的样式) 主页面

<template>
  <div id="app">
    <div class="sidebar">
      <card></card>
      <list></list>
    </div>
    <div class="main">
      <message></message>
      <usertext></usertext>
    </div>
  </div>
</template>

<script>
import card from "@/components/chat/card";
import list from "@/components/chat/list";
import message from "@/components/chat/message";
import usertext from "@/components/chat/usertext";

export default 
  name: 'Chat',
  data () 
    return 

    
  ,
  mounted:function() 
    this.$store.dispatch('initData');
  ,
  components:
    card,
    list,
    message,
    usertext
  

</script>

<style lang="scss" scoped>
#app 
  margin: 20px auto;
  width: 800px;
  height: 600px;
  overflow: hidden;
  border-radius: 10px;
  .sidebar, .main 
    height: 100%;
  
  .sidebar 
    float: left;
    color: #f4f4f4;
    background-color: #2e3238;
    width: 200px;
  
  .main 
    position: relative;
    overflow: hidden;
    background-color: #eee;
  

</style>

分模块页面 聊天框自己头像

<template>
  <div id="card">
  	<header>
  		<img class="avatar" :src="user.userface" :alt="user.name">
  		<p class="name">user.name</p>
  	</header>
  	<footer>
  		<input class="search" type="text" v-model="$store.state.filterKey" placeholder="search user...">
  	</footer>
  </div>
</template>

<script>
export default 
  name: 'card',
  data () 
    return 
      user: JSON.parse(window.sessionStorage.getItem('user'))
    
  

</script>

<style lang="scss" scoped>
#card 
	padding: 12px;
  .avatar
  	width: 40px;
  	height: 40px;
  	vertical-align: middle;/*这个是图片和文字居中对齐*/
  
  .name 
  	display: inline-block;
  	padding: 10px;
  	margin-bottom: 15px;
  	font-size: 16px;
  
  .search 
  	background: #26292E;
  	height: 30px;
  	line-height: 30px;
  	padding: 0 10px;
  	border: 1px solid #3a3a3a;
  	border-radius: 4px;
  	outline: none;/*鼠标点击后不会出现蓝色边框*/
    color: #FFF;
  

</style>

聊天页面

<template>
  <div id="message" v-scroll-bottom="sessions">
  	<ul v-if="checkUser" >
  		<li v-for="entry in  sessions[user.username + '*' + checkUser.username]">
  			<p class="time">
  				<span>entry.date | time</span>
  			</p>
  			<div class="main" :class="self:entry.self">
  				<img class="avatar" :src="entry.self ? user.userface : checkUser.userface" alt="">
  				<p class="text">entry.content</p>
  			</div>
  		</li>
  	</ul>
  </div>
</template>

<script>
import mapState from 'vuex'

export default 
  name: 'message',
  data () 
    return 
      user:JSON.parse(window.sessionStorage.getItem('user'))
    
  ,
  computed:mapState([
  	'sessions',
  	'checkUser'
  ]),
  filters:
  	time (date) 
      if (date) 
        date = new Date(date);
      
  		return `$date.getHours():$date.getMinutes()`;
  	
  ,
  directives: /*这个是vue的自定义指令,官方文档有详细说明*/
    // 发送消息后滚动到底部,这里无法使用原作者的方法,也未找到合理的方法解决,暂用setTimeout的方法模拟
    'scroll-bottom' (el) 
      //console.log(el.scrollTop);
      setTimeout(function () 
        el.scrollTop+=9999;
      ,1)
    
  

</script>

<style lang="scss" scoped>
#message 
  padding: 15px;
  max-height: 68%;
  overflow-y: scroll;
  ul 
    padding: 0px;
    list-style-type: none;
    li 
      margin-bottom: 15px;
    
  
  .time 
    text-align: center;
    margin: 7px 0;
    > span 
      display: inline-block;
      padding: 0 18px;
      font-size: 12px;
      color: #FFF;
      background-color: #dcdcdc;
      border-radius: 2px;
    
  
  .main 
    .avatar 
      float: left;
      margin: 0 10px 0 0;
      border-radius: 3px;
      width: 30px;
      height: 30px;

    
    .text 
      display: inline-block;
      padding: 0 10px;
      max-width: 80%;
      background-color: #fafafa;
      border-radius: 4px;
      line-height: 30px;
    
  
  .self 
    text-align: right;
    .avatar 
      float: right;
      margin: 0 0 0 10px;
      border-radius: 3px;
      width: 30px;
      height: 30px;
    
    .text 
      display: inline-block;
      padding: 0 10px;
      max-width: 80%;
      background-color: #b2e281;
      border-radius: 4px;
      line-height: 30px;
    
  

</style>

输入信息页面

<template>
  <div id="uesrtext">
    <textarea placeholder="按 Ctrl + Enter 发送" v-model="content" v-on:keyup="addMessage"></textarea>
  </div>
</template>

<script>
import mapState from 'vuex'

export default 
  name: 'uesrtext',
  data () 
    return 
      content:''
    
  ,
  computed:mapState([
    'checkUser'
  ]),
  methods: 
  	addMessage (e) 
  		if (e.ctrlKey && e.keyCode ===13 && this.content.length) 
  		  let msgObj = new Object();

  		  msgObj.send = this.checkUser.username;
  		  msgObj.content=this.content;
  		  this.$store.state.stomp.send('/ws/chat',,JSON.stringify(msgObj));
        this.$store.commit('addMessage',msgObj);
        this.content = '';
  		
  	
  

</script>

<style lang="scss" scoped>
#uesrtext 
	position: absolute;
  bottom: 0;
  right: 0;
  width: 100%;
  height: 30%;
  border-top: solid 1px #DDD;
  > textarea 
  	padding: 10px;
  	width: 100%;
  	height: 100%;
  	border: none;
  	outline: none;
  

</style>

朋友列表栏

<template>
  <div id="list">
  	<ul>
  		<li v-for="item in hrs" :class=" active: checkUser?item.username === checkUser.username:false " v-on:click="changeCurrentUser(item)"><!--   :class="[item.id === currentSessionId ? 'active':'']" -->
  			<img class="avatar" :src="item.userface" :alt="item.name">
  			<p class="name">item.name</p>
  		</li>
  	</ul>
  </div>
</template>

<script>
import mapState from 'vuex'

export default 
  name: 'list',
  data () 
    return 
    
  ,
  computed: mapState([
  'hrs',
  'checkUser'
	]),
  methods:
    showHrs()
      console.log(this.$store.state.hrs);
    ,
  	changeCurrentUser:function (user) 
  		this.$store.commit('changeCurrentUser',user)
  	
  ,mounted() 
    this.showHrs()
  

</script>

<style lang="scss" scoped>
#list 
  ul
    padding: 0;
  
	li 
		padding: 0px 15px;
		border-bottom: 1px solid #292C33;
		cursor: pointer;
		&:hover 
			background-color: rgba(255, 255, 255, 0.03);
		
	
  li.active /*注意这个是.不是冒号:*/
			background-color: rgba(255, 255, 255, 0.1);
	
	.avatar 
		border-radius: 2px;
		width: 30px;
		height: 30px;
		vertical-align: middle;
	
	.name 
		display: inline-block;
		margin-left: 15px;
	

</style>

三、vuex 状态管理栏

import Vue from 'vue';
import Vuex from 'vuex';
import getRequest from "@/utils/config";
import SockJS from 'sockjs-client';
import Stomp from 'stompjs';
Vue.use(Vuex);

const store = new Vuex.Store(
    state:
        routers:[],
        sessions: ,
        checkUser:null,
        filterKey:'',
        hrs:[],
        stomp:null,
        currentUser:null,
    ,
    mutations:
        initRouters(state,data)
            state.routers = data;
        ,
        changeCurrentUser (state,user) 
            state.checkUser = user;
        ,
        init_currentUser(state,currentUser)
            state.currentUser = currentUser;
        ,
        addMessage (state,msg) 
            let mess = state.sessions[state.currentUser.username+'*' + msg.send];
            if (!mess)
                Vue.set(state.sessions,state.currentUser.username+'*'+msg.send,[]);
            
            state.sessions[state.currentUser.username+'*' + msg.send].push(
                content:msg.content,
                date: new Date(),
                self:!msg.isSlef
            )
        ,
        INIT_DATA (state) 
            let data = sessionStorage.getItem('vue-chat-session');
            if (data) 
                state.sessions = JSON.parse(data);
            
        ,
        INIT_HR(state,data)
            state.hrs = data;
        

    ,
    actions: 
        initData (context) 
            context.commit('INIT_DATA');
            getRequest('/chat/hr').then(resp=>
                if (resp)
                    context.commit('INIT_HR',resp)
                
            );

            context.state.stomp = Stomp.over(new SockJS('/ws/ep'));
            context.state.stomp.connect(,success=>
                context.state.stomp.subscribe('/user/queue/chat',msg=>
                    let message = JSON.parse(msg.body);
                    message.isSlef =true;
                    message.send = message.from;
                    context.commit('addMessage',message);
                )
            ,error=>

            )
        
    
)

store.watch(function (state) 
    return state.sessions
,function (val) 
    sessionStorage.setItem('vue-chat-session', JSON.stringify(val));
,
    deep:true/*这个貌似是开启watch监测的判断,官方说明也比较模糊*/
)

export default store;

四、补充 

vuex的mutations方法在页面刷新时,会重新加载vuex,所以此时获取到的数据会加载不到,如果用到获取属性时会报错,比如我在登录时获取用户数据,并commit到mutations,然后拿到用户名做操作,但是刷新时用户信息会没有,导致报错。解决方法如下

在APP.vue中

<script>
export default 
  name: 'App',
  created() 
    //在页面加载时读取sessionStorage里的状态信息
    if (sessionStorage.getItem('store')) 
      this.$store.replaceState(Object.assign(, this.$store.state, JSON.parse(sessionStorage.getItem('store'))));
    

    //在页面刷新时将vuex里的信息保存到sessionStorage里
    window.addEventListener('beforeunload', () => 
      sessionStorage.setItem('store', JSON.stringify(this.$store.state));
    );
  

</script>
<style>

五、效果展示

发消息

 收消息

 收发

 

 

springboot+vue3集成使用websocket(代码片段)

...ocket</artifactId></dependency>增加配置类,声明该springboot项目使用websocket@ConfigurationpublicclassWebSocketConfig@BeanpublicServerEndpointExporterserverEndpointExporter()returnnewServerEndpointExporter();第三步,新建包增加业务代码:... 查看详情

springboot+websocket+vue+vuex实现在线聊天(客户端)(代码片段)

一、使用node代理ws请求proxyObj['/ws']=ws:true,target:"ws://localhost:8081"导入连接需要连接websocket的js npminstallsockjs-clientnpminstallstompjsnpminstallsass-loader@8.0.2--save//这个是css写法需要用到 查看详情

基于websocket协议的研究demo

1、日志推送 websocket在线测试WebSocket在线测试工具物联网http://www.websocket-test.com/2、Springboot+vue的聊天:Springboot+websocket+vue的web聊天项目https://gitee.com/xzlmk/spring_boot_vue_chat 3、实时通信  4、基于C#net4.5实现最 查看详情

springboot+vue+websocket实现服务器端向客户端主动发送消息

参考技术A本文通过一个实际的场景来介绍在前后端分离的项目中通过WebSocket来实现服务器端主动向客户端发送消息的应用。主要内容如下Websocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket连接成功后,服务端与客户... 查看详情

springboot及springcloud实现websocket群发及单点发送

参考技术A引入3个文件1.WebSocketConfig2.WebSocketServer3、SendPassagesController4.前端页面(注意改一下)vue版本自行百度后端向前端推送数据 查看详情

基于websocket协议的研究demo

...试WebSocket在线测试工具物联网http://www.websocket-test.com/2、Springboot+vue的聊天:Springboot+websocket+vue的web聊天项目https://gitee.com/xzlmk/spring_boot_vue_chat 3、实时通信  4、基于C#net4.5实现最简单的websocket客户端和服务端https://blog.csdn... 查看详情

java项目:在线淘房系统(租房购房)(java+springboot+redis+mysql+vue+springsecurity+jwt+elasticsearch+websocket)

...所有房屋信息、管理所有预约信息等等。应用技术:SpringBoot+Red 查看详情

springboot+websocket+vue+peerjs实现webrtc视频通话功能(代码片段)

开发背景博主正在担任一款电商app的全栈开发,其中涉及到一个视频通话功能。但是由于业务需求及成本考虑,不能使用第三方提供的SDK进行开发。所以博主选择使用PeerJs+WebSocket来实现这个功能。专业名词、术语解释... 查看详情

springboot使用websocket

目录springboot使用WebSocket前端:后端springboot使用WebSocket来源:https://blog.lqdev.cn/2018/08/14/springboot/chapter-nineteen/类似聊天室的功能,WebSocket是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议。在WebSocketAPI中,浏览器和服务器只... 查看详情

springboot+websocket

springboot+websocket:先引入websocket的依赖包<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>html: 查看详情

springboot+websocket学习(代码片段)

Springboot+WebSocket聊天室项目WebSocket介绍WebSocket的特点webSocket协议客户端(浏览器)实现websocket对象websocket事件WebSocket方法服务端实现服务端如何接受客户端发送过来的数据呢?服务端如何推送数据给客户端呢?基于WebSocket的网页聊... 查看详情

springboot整合websocket简单聊天室(代码片段)

springboot整合websocket(一)简单聊天室springboot整合websocket(一)简单聊天室springboot整合websocket(二)上传文件(引导篇)springboot整合websocket(三)上传文件(终篇& 查看详情

springboot之集成websocket

websocket是什么不做介绍。开发环境:jdk1.8,win7_64旗舰版,idea 1、初始化一个springboot项目 2、加入websocket依赖<!--springboot的websocket依赖--><dependency><groupId>org.springframework.boot</groupId>&l 查看详情

springboot创建websocket组件

创建新工程:NextNextNextFinish  查看详情

springboot实现websocket(代码片段)

...一个websocket应该怎么实现,这里采用的是更加方便的Springboot的方式,如果项目中没有使用springboot框架,也是可以 查看详情

springboot实现websocket(代码片段)

...一个websocket应该怎么实现,这里采用的是更加方便的Springboot的方式,如果项目中没有使用springboot框架,也是可以 查看详情

springboot实现websocket(代码片段)

...一个websocket应该怎么实现,这里采用的是更加方便的Springboot的方式,如果项目中没有使用springboot框架,也是可以 查看详情

springboot+websocket示例

【转】springboot+websocket示例1、新建maven工程工程结构如下:完整的pom.xml如下:<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instan 查看详情