编辑
2024-04-22
Tauri
00

目录

甲、环境Tauri跨端程序
乙、下载最新的Geoserver二进制文件
丙、 下载最低17版本的java
丁、 设置Tauri 打包文件
戍、rust执行终端命令唤起geoserver
1) 使用std::env::current_dir判断文件是否存在
2) 使用std::process::Command执行终端命令
3) 使用std::net::UdpSocket::bind获取当前设备IP
己、唤起服务
庚、得设置允许http使用

GeoServer在Tauri中无感启动与使用

吃力不讨好的事情

PC端加载至少1G的tif文件到地图中展示
离谱
切片都不帮个忙
这不难为老实人么

tauri+geoserver


甲、环境Tauri跨端程序

前端

  • [✅] 得升级@tauri-apps/cli>=2.0.0-beta.0
  • [✅] - @tauri-apps/api >=2.0.0-beta.0

rust

  • [✅] 得升级tauri-build2.0.0-beta.10
  • [✅] - tauri 2.0.0-beta.13

乙、下载最新的Geoserver二进制文件

一定🏳️
一定🏳️
一定🏳️
下载二进制文件Platform Independent Binary

Geoserver Platform Independent Binary


丙、 下载最低17版本的java

一定🏳️
一定🏳️
一定🏳️
下载免安装解压即用的

java_17 zip


丁、 设置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 },
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:还是夸张一点

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

还是夸张一点技术专栏 © 2019 - 2023 | 滇ICP备2022001556号
世间情动不过盛夏白瓷梅子汤,碎冰碰壁当啷响。