[开发心得]websocket vue springboot使用
前言: 这篇文章的名字为了方便百度搜索,显得不是很规整。
websocket 的相关概念,实现方式这里不做赘述,有一些场景,不适合前端长轮询。所以通常采用后端主动通知的方式。
Springboot部分:
版本号由官方“仲裁“获得:
<!-- ws 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
websocket配置: (注意点:要注入ServerEndpointExporter,这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint。要注意,如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。)
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
/**
* 方法描述 Websocket配置
* @since:
* @param:
* @return:
* @author:
* @date:
*/
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
发布类:
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @Author:
* @Date:
* @Description:
*/
@Slf4j
@ServerEndpoint("/websocket/{username}")
@Component
public class WebSocketController {
// 连接数
private static int onlineCount = 0;
private static Map<String,WebSocketController> clients =new ConcurrentHashMap<>();
private Session session;
private String username;
/**
* 方法描述 连接成功调用的方法
* @since:
* @param: * @param username
* @param session
* @return: void
* @author:
* @date:
*/
@OnOpen
public void onOpen(@PathParam("username") String username,Session session){
this.username = username;
this.session = session;
WebSocketController.onlineCount ++;
log.info("响应新连接,当前连接数为:{}",onlineCount);
clients.put(username,this);
}
@OnClose
public void onClose(){
clients.remove(username);
WebSocketController.onlineCount--;
log.info("发现客户端断开链接,当前连接数为:{}",onlineCount);
}
@OnMessage
public void onMessage(String message){
log.info("message:{}",message);
}
@OnError
public void onError(Session session,Throwable throwable){
log.error("ws eror:{}",throwable.getMessage());
}
// 消息群发
public static void sendMessage(String message){
for(WebSocketController item : clients.values()){
item.session.getAsyncRemote().sendText(message);
}
}
// 消息发送指定
public static void sendMessagePoint(String message,Session session){
session.getAsyncRemote().sendText(message);
}
}
Vue部分:
十分要注意的地方就是,data里边要放一个websocket变量用来承接(类似的教程网上一大把,但是就是没人喜欢说这块):
data() {
return {
websocket: ''
}
}
该方法可以在created 或者 mounted钩子函数执行的时候调用,一般建议mounted,除非在构建页面的时候,需要立马与后端通信.
另外,要注意,WebSocket无需额外引入,直接可以用的,但是要注意大小写区分问题:WebSocket
initWebSocket() {
let socktUrl = 'ws://xxxx:8080/websocket/{' + this.username + '}';
this.websocket = new WebSocket(socktUrl);
this.websocket.onopen = this.open;
this.websocket.onerror = this.error;
this.websocket.onmessage = this.getMessage;
this.websocket.onclose = this.close;
},
open() {
console.log('socket连接成功')
},
error() {
console.log('连接错误')
},
getMessage(msg) {
// 从后端获取到消息1.确定是哪个素材的,如果素材在当页,就直接控制其进度条.后端需要给前端传递{id:"",process:""}类型的数据
console.log('收到消息' + msg);
},
send() {
this.socket.send()
},
close() {
console.log('socket已经关闭')
}
},
destroyed() {
if (this.socket) {
this.socket.close();
}
}
关于测试和调用.这里不做详解,后端可以专门写一个测试接口用来供给调用,用来处理后端给前端测试,如直接调用 WebSocketController.sendMessage()方法.是群发还是指定发给某台机器,需要根据业务来定.