前言 上回說到,利用vite載入不同mode下的配置文件,可以實現不同運行環境下的參數配置。在前端應用中經常使用到Websocket,其地址同樣可以在.env中間中配置。 代碼 vite.config.ts代碼的執行是在createApp之前,不可以在vite.config.ts中使用例如pinia ...
前言
上回說到,利用vite載入不同mode下的配置文件,可以實現不同運行環境下的參數配置。在前端應用中經常使用到Websocket,其地址同樣可以在.env中間中配置。
代碼
vite.config.ts代碼的執行是在createApp之前,不可以在vite.config.ts中使用例如pinia
、router
等組件。可以使用import.meta.env獲取配置文件中的參數
廢話少說,直接上代碼。
前端
.env.development
# 開發環境配置
NODE_ENV='development'
# 本地服務埠
VITE_PORT=8093
.......
# Websocket服務地址
VITE_WS_URL='ws://localhost:8083'
demo.vue
const wsPath = import.meta.env.VITE_WS_URL + 'ws/demo';
let wsSocket: any;
function wsInit() {
if (typeof (WebSocket) === 'undefined') {
console.log("瀏覽器不支持websocket");
} else {
wsSocket = new WebSocket(wsPath);
wsSocket.onopen = open;
wsSocket.onerror = error;
wsSocket.onmessage = getMessage;
}
}
function open() {
console.log("websocket連接成功")
}
function error(error: string) {
console.log("websocket連接錯誤", error)
}
function getMessage(msg: MessageEvent) {
let states = msg.data;
states = JSON.parse(states);
states.forEach((dataItem: any) => {
});
}
function send(params: string) {
wsSocket.send(params)
}
function close(e: any) {
console.log("websocket連接關閉")
}
onMounted(() => {
wsInit();
})
onUnmounted(() => {
wsSocket.onclose = close;
})
後端
Websocket.config.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
DemoWebsocketServer.java
import io.micrometer.common.util.StringUtils;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@Component
@ServerEndpoint(value = "/ws/demo")
public class DemoWebsocketServer {
private static ConcurrentHashMap<String, DemoWebsocketServer> webSocketMap = new ConcurrentHashMap<>();
@Getter
private Session session;
public String pointsUrl;
private static StringRedisTemplate stringRedisTemplate;
@Autowired
public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate) {
DemoWebsocketServer.stringRedisTemplate = stringRedisTemplate;
}
/**
* 連接建立成功調用的方法
*/
@OnOpen
public void onOpen(Session session) {
this.session = session;
log.info("{}連接成功", this.getSession());
webSocketMap.put(session.getId(), this);
sendMessage("");
}
@OnMessage
public void onMessage(String message) {
// todo 獲取前端發送過來的
}
/**
* 連接關閉調用的方法
*/
@OnClose
public void onClose() {
//從set中刪除
webSocketMap.remove(this.getSession().getId());
log.info("斷開連接" + this.getSession());
}
/**
* @param error
*/
@OnError
public void onError(Throwable error) {
if (error.getMessage().contains("Broken pipe")) {
log.info("客戶端突然斷開連接");
} else {
System.out.println("發生錯誤");
error.printStackTrace();
}
}
/**
* 實現伺服器主動推送
*/
public void sendMessage(String message) {
synchronized (webSocketMap) {
if (!StringUtils.isEmpty(this.getSession().getId()) && webSocketMap.containsKey(this.getSession()
.getId())) {
try {
webSocketMap.get(this.getSession().getId()).getSession().getBasicRemote().sendText(message);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
DemoWebsocketServer that = (DemoWebsocketServer) o;
return Objects.equals(session, that.session) && Objects.equals(pointsUrl, that.pointsUrl);
}
@Override
public int hashCode() {
return Objects.hash(session, pointsUrl);
}
}