将Geoserver服务打包到Tauri程序中使用

GeoServer在Tauri中无感启动与使用

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


甲、环境Tauri跨端程序

前端

  • ✅\] 得升级`@tauri-apps/cli`到`>=2.0.0-beta.0`

rust

  • ✅\] 得升级`tauri-build`到`2.0.0-beta.10`


乙、下载最新的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
    },
相关推荐
IT枫斗者5 小时前
前端部署后如何判断“页面是不是最新”?一套可落地的版本检测方案(适配 Vite/Vue/React/任意 SPA)
前端·javascript·vue.js·react.js·架构·bug
laowangpython7 小时前
Rust 入门:GitHub 热门内存安全编程语言
开发语言·其他·rust·github
倾颜9 小时前
React 19 源码主线拆解 04:Fiber 到底是什么,React 为什么需要 Fiber?
前端·react.js·源码阅读
老王以为11 小时前
为什么 React 和 Vue 不一样?
前端·vue.js·react.js
迪菲赫尔曼14 小时前
从 0 到 1 打造工业级推理控制台:UltraConsole(Ultralytics + FastAPI + React)开源啦!
前端·yolo·react.js·计算机视觉·开源·fastapi
Highcharts.js14 小时前
React 开发实战:如何使用 useEffect 为 Highcharts 注入实时数据
前端·javascript·react.js·开发实战·实时数据·highcharts·轮询数据
fox_lht15 小时前
第十章 通用集合
开发语言·后端·算法·rust
光影少年16 小时前
前端SSR和ssg区别
前端·vue.js·人工智能·学习·react.js
祖国的好青年16 小时前
VS Code 搭建 React Native 开发环境(Windows 实战指南)
android·windows·react native·react.js