java后端和VUE2前端使用websocket实现与客户端之间接收及发送消息
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
免费下载资源
·
客户端请求websocket接口,连接通道=》我这边业务成功客户端发消息=》客户端自动刷新。
接口:ws://localhost:8080/websocket/xx
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* @author Administrator
*/
@Configuration
public class WebSocketConfig implements WebSocketConfigurer {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
package com.xx.framework.web.service;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
@Component
@Slf4j
@ServerEndpoint("/websocket/{key}")
public class WebSocketService {
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
private static CopyOnWriteArraySet<WebSocketService> webSockets = new CopyOnWriteArraySet<>();
private static WebSocketService webSocketService;
@PostConstruct
public void init(){
webSocketService = this;
}
/**
* 连接成功后调用的方法
* @param session
* @param key
*/
@OnOpen
public void onOpen(Session session,@PathParam("key") String key){
//key作为前端传给后端的参数值
this.session = session;
webSockets.add(this);
log.info("websocket连接成功");
log.info("websocket有新的连接,连接总数为"+webSockets.size());
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(){
this.session = null;
webSockets.remove(this);
log.info("websocket连接关闭");
}
/**
* 收到客户端消息后调用的方法,根据业务要求进行处理,这里就简单地将收到的消息直接群发推送出去
* @param message 客户端发送过来的消息
*/
@OnMessage
public void onMessage(Session session,String message){
if (StrUtil.isNotBlank(message)){
if(message.equals("heartbeat")){
sendTextMessage(session,"已连接");
}
}
log.info("WebSocket收到客户端消息:"+message);
}
/**
* 实现服务器主动推送消息
* @param session = sessionPool.get(key);
* @param message
*/
private void sendTextMessage(Session session, String message) {
if (session != null){
try {
session.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void sendAllMessage(String message){
log.info("websocket消息全部人员消息:"+message);
for (WebSocketService apiWebSocketService:webSockets){
try{
if (apiWebSocketService.session.isOpen()){
apiWebSocketService.session.getAsyncRemote().sendText(message);
}
}catch (Exception e){
e.printStackTrace();
log.error("全部人员发送消息失败:",e.getMessage());
}
}
}
/**
* 发生错误时的回调函数
* @param session
* @param error
*/
@OnError
public void onError(Session session,Throwable error){
log.error("发生错误");
error.printStackTrace();
}
}
经测试,成功
如果是线上服务器连接,则需要在nginx里配置websocket相关内容,再重启nginx,代码如下
server {
listen 443 ssl;
server_name api.kadecard.com;
ssl_certificate cert.pem;
ssl_certificate_key cert.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://xx:7878/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
#websocket 这里的websocket是后端websocket接口的接口名称
location /websocket {
rewrite ^/ws$ / break;
rewrite ^/ws(.*)$ $1 break;
proxy_pass http://127.0.0.1:7878;
proxy_http_version 1.1; #websoket必须要使用的协议,http 1.1
proxy_set_header Upgrade $http_upgrade; #要使用websocket协议时,响应http升级请求
proxy_set_header Connection "upgrade";
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_read_timeout 600s;
}
}
本地连接的时候用的是ws://,因为是http链接,但是如果是服务器连接,且支持https连接方式,则就需要用wss://的连接方式。
如果是在 宝塔配置,则如下:
location /websocket {
##后台服务器地址加上websocket的接口名称
proxy_pass http://localhost:8084/websocket/; #这里是http不是ws,不用怀疑,代理的ip和port写ws访问的实际地址
proxy_http_version 1.1; #这里必须使用http 1.1
#下面两个必须设置,请求头设置为ws请求方式
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
还要检查接口权限是否开放:
类型:SecurityConfig
.antMatchers("/login", "/register", "/captchaImage","/rinter/**","/websocket/**").permitAll()
前端vue:
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<el-input type="text" v-model="msgNew" label="新值"></el-input>
<el-button type="primary" @click="change()">改变值</el-button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
data () {
return {
path:"ws://127.0.0.1:8088/websocket/"+this.algorithm(),
socket:"",
msgNew:'',
}
},
mounted () {
// 初始化
this.init()
},
methods: {
algorithm:function(){
let abc=['a','b','c','d','e','f','g','h','i','g','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
let [max,min]=[Math.floor(Math.random()*(10-7+1)+1),Math.floor(Math.random()*(17-10+1)+17)];
abc=abc.sort(()=>0.4-Math.random()).slice(max,min).slice(0,8).join("");
var a=new Date().getTime()+abc;
return a
},
change(){
this.msg=this.msgNew;
this.socket.send(this.msgNew);
},
init: function () {
if(typeof(WebSocket) === "undefined"){
alert("您的浏览器不支持socket")
}else{
// 实例化socket
this.socket = new WebSocket(this.path)
// 监听socket连接
this.socket.onopen = this.open
// 监听socket错误信息
this.socket.onerror = this.error
// 监听socket消息
this.socket.onmessage = this.getMessage
}
},
open: function () {
console.log("socket连接成功")
this.socket.send("heartbeat");
},
error: function () {
console.log("连接错误")
this.init()
},
getMessage: function (msg) {
console.log("数据接收:"+msg.data)
this.msg=msg.data
},
// 发送消息给被连接的服务端
send: function (params) {
console.log("发送消息给服务端")
this.socket.send(params)
},
close: function () {
console.log("socket已经关闭")
}
},
destroyed () {
// 销毁监听
this.socket.onclose = this.close
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
main.js文件配置:
import global from '@/utils/wsGlobal.js'
Vue.prototype.$global=global;
初始化的时候设置:
this.socket = new WebSocket(this.path+this.token)
this.$global.setWs(this.socket)
其他页面引用:
例如消息获取:
mounted() {
this.$global.ws.onmessage=this.websocketonmessage
},
methods: {
websocketonmessage(e){
console.log("数据接收"+e.data);
}
}
GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891
Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
更多推荐
已为社区贡献1条内容
所有评论(0)