GeoServer在Tauri中无感启动与使用
吃力不讨好的事情 PC端加载至少1G的tif文件到地图中展示
离谱
切片都不帮个忙
这不难为老实人么
甲、环境Tauri
跨端程序
前端
- [✅] 得升级
@tauri-apps/cli
到>=2.0.0-beta.0
- [✅] -
@tauri-apps/api
>=2.0.0-beta.0
rust
- [✅] 得升级
tauri-build
到2.0.0-beta.10
- [✅] -
tauri
2.0.0-beta.13
乙、下载最新的Geoserver
二进制文件
一定🏳️
一定🏳️
一定🏳️
下载二进制文件
Platform Independent Binary
Geoserver Platform Independent Binary
丙、 下载最低17
版本的java
一定🏳️
一定🏳️
一定🏳️
下载免安装解压即用的
丁、 设置Tauri
打包文件
tauri.conf.json
json
"resources": [
"./resources/geoserver-main-latest-bin"
]
文件geoserver-main-latest-bin
中需要包含下载解压的java_17
最终项目结构是
-
src-tauri/resources/geoserver-main-latest-bin
--bin
--data_dir
--etc
--jdk_17
--lib
--license
--licenses
--log
--modules
--resources
--webapps
--start.ini
--start.jar
--VERSION.txt
戍、rust
执行终端命令唤起geoserver
1) 使用std::env::current_dir
判断文件是否存在
rust
let binding = env::current_dir().unwrap().join("resources/geoserver-main-latest-bin");
let flag = is_path_exists(binding.to_str().unwrap());
2) 使用std::process::Command
执行终端命令
rust
//CREATE_NO_WINDOW 叮嘱此变量是设置终端命令执行时不创建终端窗口(仅限window)
let binding = env::current_dir().unwrap().join("resources/geoserver-main-latest-bin");
let java_path = binding.join(r"jdk_17/bin/java.exe");
let jar_path = binding.join(r".\start.jar");
const CREATE_NO_WINDOW: u32 = 0x08000000;
let command = Command::new(java_path)
.arg("-jar")
.arg(jar_path)
.current_dir(binding)
.creation_flags(CREATE_NO_WINDOW)
.spawn();
3) 使用std::net::UdpSocket::bind
获取当前设备IP
rust
fn get_local_ip() -> Option<IpAddr> {
let socket = match std::net::UdpSocket::bind("0.0.0.0:0") {
Ok(socket) => socket,
Err(_) => return None,
};
match socket.connect("8.8.8.8:80") {
Ok(()) => (),
Err(_) => return None,
}
socket.local_addr().ok().map(|addr| addr.ip())
}
fn is_port_available(ip: IpAddr, port: u16) -> bool {
let addr = SocketAddr::new(ip, port);
TcpStream::connect(addr).is_ok()
}
#[tauri::command]
pub async fn get_localhost_ip() -> Result<CustomResult> {
if let Some(ip) = get_local_ip() {
println!("Local IP address: {}", ip);
let port = 28080;
if is_port_available(ip, port) {
return Ok(CustomResult::new(true, 200, "Success", Some(json!({
"ip": ip,
"port": port
}))));
} else {
return Err(CustomResult::new(false, 500, &format!("Port {} is not available", port), None));
}
} else {
return Err(CustomResult::new(false, 500, "Failed to get local IP address", None));
}
}
CustomResult
是我自定义的内容返回格式,请自行处理
己、唤起服务
不在项目启动时唤起,单独开启子进程会阻塞主进程
在前端初始化时在进行
IPC
通信唤起设置打开
Geoserver
时单独唤起一个webview
ts
import { invokeGeoServerExist, invokeGeoServerStart, invokeGetLocalhostIp } from "@/ipc-apps/invoke.geoserver";
import { ResultMeta } from "@/types/result";
import { useEffect, useState } from "react";
import { WebviewWindow } from '@tauri-apps/api/webviewWindow';
export const useGeoServerClient = () => {
const [isExist, setExist] = useState<boolean>(false);
const [isStart, setStart] = useState<boolean>(false);
const [ipAddress, setIpAddress] = useState<{
address: string,
msg: string
}>({
address: '',
msg: 'GeoServer服务未启动'
})
const queryGeoServer = async () => {
invokeGeoServerExist().then((res: ResultMeta) => {
console.log('是否存在 = ',res.success);
if(res.success){
setExist(true);
invokeGeoServerStart().then((res: ResultMeta) => {
console.info('geoserver启动成功');
// res.success && setStart(true);
})
}
})
}
const geoserverUrl = (_isStart: boolean, uri: string) => {
if(!_isStart)return;
const webview = new WebviewWindow("geoserver-window", {
url: `${uri}/geoserver/index.html`,
x: 0,
y: 0,
width: 1440,
height: 1080,
title: "GeoServer自启服务",
});
webview.once('tauri://created', function () {
// webview 窗口成功创建
console.log('成功');
});
webview.once('tauri://error', function (e) {
// 创建窗口时出现错误
console.log('错误, ', e);
});
}
useEffect(() => {
console.log("是否启动 = ", isExist);
if(isExist){
const _timer = setInterval(() => {
invokeGetLocalhostIp().then(res => {
console.log('res =', res);
if(res.success){
setStart(true)
const {
ip, port
} = res.payload;
setIpAddress({
address: `http://${ip}:${port}`,
msg: 'GeoServer服务已启动'
})
clearInterval(_timer)
}else{
setIpAddress({
address: "",
msg: res.msg
})
}
})
}, 1000)
}
}, [isExist])
return {
isStart,
ipAddress,
isExist,
queryGeoServer,
geoserverUrl
}
}
庚、得设置允许http
使用
tauri.conf.json
json
"security": {
"csp": null
},