Rust配置开发环境+服务器实战

https://www.cnblogs.com/skzxc/p/12129353.html

  1. 默认已经安装好MSVC。

  2. 官网https://www.rust-lang.org/zh-CN/learn/get-started安装Rust安装器,选择winodwsx64版本

  3. 运行安装,将文件夹移动到D盘,安装后,文件夹在C:\Users\xxx下有.cargo.rustup两个文件夹

  4. 新建环境变量

    CARGO_HOME
    D:\Users\xxx\.cargo
    
    RUSTUP_HOME
    D:\Users\xxx\.rustup
    
    path
    %CARGO_HOME%\bin
    
  5. 测试安装成功,输入命令

    cargo --version
    rustup --version
    
  6. 环境变量配置加速安装地址

    RUSTUP_DIST_SERVER
    https://mirrors.tuna.tsinghua.edu.cn/rustup
    RUSTUP_UPDATE_ROOT
    https://mirrors.tuna.tsinghua.edu.cn/rustup/rustup
    
  7. 配置库镜像,在C:\Users\xxx\.cargo下创建config.toml文件,无后缀,复制粘贴

    [source.crates-io]
    registry = "https://github.com/rust-lang/crates.io-index"
    replace-with = "tuna"
    [source.tuna]
    registry = "https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git"
    
  8. 运行安装程序。

  9. 安装VSCode插件

    • Rust Analyzer
    • Even Better TOML
    • CodeLLDB

开发示例

下面包含给出一个Rust服务器的开发示例

给出需求:

  1. 接收两个可选参数:
    1. html_path:默认为index.html,带有路径检查
    2. port:默认为8787
  2. 保存变量html_path,每次浏览器端刷新时,都实时读取html_path返回给服务器渲染。这是为了方便开发和调试。
  3. 开放静态资源给前端。
  4. 允许前端通过/write?filepath=xxx,以及body的数据,写入到服务器端。

开发步骤:

  1. 新建一个项目,命令行输入cargo new myproject

  2. 测试环境配置,编译cargo build

  3. 测试环境配置,运行cargo run

  4. cargo.toml中,复制粘贴

    [package]
    name = "mini_server"
    version = "0.1.0"
    edition = "2024"
    
    [dependencies]
    hyper = { version = "0.14", features = ['full']}
    tokio = { version = "1", features = ["full"] }
    url = '2.3'
    mime_guess = "2.0"
    
  5. src/main.rs中,复制粘贴

    use hyper::service::{make_service_fn, service_fn};
    use hyper::{Body, Method, Request, Response, Server, StatusCode};
    use std::fs;
    use std::net::SocketAddr;
    use std::path::Path;
    use std::sync::Arc;
    use tokio::signal;
    use hyper::body::to_bytes;
    use url::form_urlencoded;
    use mime_guess::from_path;
    
    #[tokio::main]
    async fn main() {
        // 从命令行参数获取HTML文件路径和端口号
        let args: Vec<String> = std::env::args().collect();
        let html_file_path = args.get(1).map(|s| s.as_str()).unwrap_or("index.html");
        let port = args.get(2).and_then(|s| s.parse::<u16>().ok()).unwrap_or(8787);
    
        // 检查文件是否存在
        if !Path::new(html_file_path).exists() {
            eprintln!("File not found: {}", html_file_path);
            return;
        }
    
        // 将HTML文件路径存储在Arc中以便在多个请求之间共享
        let html_file_path = Arc::new(html_file_path.to_string());
    
        // 定义服务处理函数
        let make_svc = make_service_fn(move |_conn| {
            let html_file_path = Arc::clone(&html_file_path);
            async move {
                Ok::<_, hyper::Error>(service_fn(move |req| {
                    let html_file_path = Arc::clone(&html_file_path);
                    async move {
                        handle_request(req, html_file_path).await
                    }
                }))
            }
        });
    
        // 定义服务器地址
        let addr = SocketAddr::from(([127, 0, 0, 1], port));
    
        // 启动服务器
        let server = Server::bind(&addr).serve(make_svc);
    
        // 处理服务器关闭信号
        let graceful = server.with_graceful_shutdown(shutdown_signal());
    
        println!("Server running at http://{}", addr);
    
        // 运行服务器
        if let Err(e) = graceful.await {
            eprintln!("Server error: {}", e);
        }
    }
    
    // 处理HTTP请求
    async fn handle_request(
        req: Request<Body>,
        html_file_path: Arc<String>,
    ) -> Result<Response<Body>, hyper::Error> {
        match (req.method(), req.uri().path()) {
            // 返回HTML内容
            (&Method::GET, "/") => {
                match read_file_to_string(&html_file_path) {
                    Ok(content) => Ok(Response::new(Body::from(content))),
                    Err(e) => {
                        let response = Response::builder()
                            .status(StatusCode::INTERNAL_SERVER_ERROR)
                            .body(Body::from(format!("Failed to read HTML file: {}", e)))
                            .unwrap(); // This unwrap is safe because we know the builder is correctly configured
                        Ok(response)
                    }
                }
            }
    
            // 处理文件写入请求
            (&Method::POST, "/write") => {
                // 解析查询参数
                let query = req.uri().query().unwrap_or_default();
                let params: Vec<(String, String)> = form_urlencoded::parse(query.as_bytes())
                    .into_owned()
                    .collect();
    
                // 获取文件路径参数
                let file_path = params
                    .iter()
                    .find(|(key, _)| key == "filepath")
                    .map(|(_, value)| value.to_string())
                    .unwrap_or_else(|| "example.txt".to_string());
    
                // 读取请求体内容
                let body_bytes = to_bytes(req.into_body()).await?;
                let body_content = String::from_utf8(body_bytes.to_vec()).unwrap_or_default();
    
                // 写入文件
                match write_string_to_file(&file_path, &body_content) {
                    Ok(_) => Ok(Response::new(Body::from("File written successfully"))),
                    Err(e) => {
                        let response = Response::builder()
                            .status(StatusCode::INTERNAL_SERVER_ERROR)
                            .body(Body::from(format!("Failed to write file: {}", e)))
                            .unwrap(); // This unwrap is safe because we know the builder is correctly configured
                        Ok(response)
                    }
                }
            }
    
            (&Method::GET, path) => {
                // 构建文件路径
                let file_path = format!(".{}", path);
                match read_file_to_bytes(&file_path) {
                    Ok(content) => {
                        // 根据文件扩展名猜测MIME类型
                        let mime_type = from_path(&file_path).first_or_octet_stream();
                        let response = Response::builder()
                            .header("Content-Type", mime_type.as_ref())
                            .body(Body::from(content))
                            .unwrap(); // This unwrap is safe because we know the builder is correctly configured
                        Ok(response)
                    }
                    Err(_) => {
                        // 文件不存在,返回404 Not Found
                        let response = Response::builder()
                            .status(StatusCode::NOT_FOUND)
                            .body(Body::from("Not Found"))
                            .unwrap(); // This unwrap is safe because we know the builder is correctly configured
                        Ok(response)
                    }
                }
            }
    
            // 返回404 Not Found
            _ => {
                let response = Response::builder()
                    .status(StatusCode::NOT_FOUND)
                    .body(Body::from("Not Found"))
                    .unwrap(); // This unwrap is safe because we know the builder is correctly configured
                Ok(response)
            }
        }
    }
    
    // 处理服务器关闭信号
    async fn shutdown_signal() {
        // 等待Ctrl+C信号
        signal::ctrl_c()
            .await
            .expect("Failed to install CTRL+C signal handler");
        println!("Shutting down server...");
    }
    
    // 读取文件内容为字符串
    fn read_file_to_string(file_path: &str) -> Result<String, std::io::Error> {
        fs::read_to_string(file_path)
    }
    
    // 将字符串写入文件
    fn write_string_to_file(file_path: &str, content: &str) -> Result<(), std::io::Error> {
        fs::write(file_path, content)
    }
    
    // 读取文件内容为字节数组
    fn read_file_to_bytes(file_path: &str) -> Result<Vec<u8>, std::io::Error> {
        fs::read(file_path)
    }
    
  6. cargo build。让大模型生成一个index.html文件,与生成的exe放进文件夹,点击运行即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/980235.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【前端基础】Day 7 CSS高级技巧

目录 1. 精灵图 1.1 为什么需要精灵图 1.2 精灵图&#xff08;sprites&#xff09;的使用 2. 字体图标 2.1 字体图标的产生 2.2 字体图标的优点 2.3 字体图标的下载 2.4 字体图标的引入 2.5 字体图标的追加 3. CSS三角形 4. CSS用户界面样式 4.1 更改用户鼠标样式 …

React低代码项目:问卷编辑器 II

吐司问卷&#xff1a;问卷编辑器 II Date: February 26, 2025 Log **软件设计的可拓展性&#xff1a;**对修改封闭&#xff0c;对拓展开放 工具栏 删除组件 需求&#xff1a; 要点&#xff1a; 实现删除选中组件 思路&#xff1a;重新计算 selectedId&#xff0c;优先选择…

图像处理之图像边缘检测算法

目录 1 图像边缘检测算法简介 2 Sobel边缘检测 3 经典的Canny边缘检测算法 4 演示Demo 4.1 开发环境 4.2 功能介绍 4.3 下载地址 参考 1 图像边缘检测算法简介 图像边缘检测是计算机视觉和图像处理中的基本问题&#xff0c;主要目的是提取图像中明暗变化明显的边缘细节…

数据结构(初阶)(八)----排序

排序 概念 排序&#xff1a;所谓排序&#xff0c;就是使⼀串记录&#xff0c;按照其中的某个或某些关键字的⼤⼩&#xff0c;递增或递减的排列起来的 操作。 比较排序 插入排序 直接插入排序 直接插⼊排序是⼀种简单的插⼊排序法&#xff0c;其基本思想是&#xff1a;把待…

计算机毕业设计SpringBoot+Vue.js基于JAVA语言的在线考试与学习交流网页平台(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

聊一聊 IM 如何优化数据库

IM 系列 im doc 实时通讯文档仓库 聊一聊 IM 是什么&#xff1f; IM 即时通讯系统概览 聊一聊 IM 要如何设计&#xff1f; 聊一聊 IM 要如何设计功能模块&#xff1f; 聊一聊 IM 要如何进行架构设计&#xff1f; 聊一聊 IM 要如何进行技术选型&#xff1f; 聊一聊 IM 要…

人工智能AI在汽车设计领域的应用探索

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 简单&#xff0c;单纯&#xff0c;喜欢独处&#xff0c;独来独往&#xff0c;不易合同频过着接地气的生活…

DeepSeek-R1 大模型实战:腾讯云 HAI 平台 3 分钟极速部署指南

引言&#xff1a;为什么选择 DeepSeek-R1&#xff1f; 近期&#xff0c;国产大模型 DeepSeek-R1 因其低成本、高性能的特点在全球 AI 领域引发热议。根据 Sensor Tower 数据&#xff0c;其发布仅 18 天便斩获 1600 万次下载量&#xff0c;远超 ChatGPT 同期表现。而腾讯云推出…

[SWPUCTF 2022 新生赛]1z_unserialize

题目描述&#xff1a;是很简单的反序列化噢 代码审计看注释 <?phpclass lyh{ //定义一个类为lyhpublic $url NSSCTF.com;//公共属性&#xff0c;初始值为NSSCTF.compublic $lt; //公共属性&#xff0c;没有初始值public $lly; //公共属性&…

三支一扶入职体检不合格项目全解析

“三支一扶” 计划为高校毕业生提供了到基层服务的宝贵机会&#xff0c;通过层层选拔后&#xff0c;入职体检也是其中关键的一环。了解哪些项目可能导致体检不合格&#xff0c;能让大家提前做好准备&#xff0c;避免在这一步出现意外。接下来&#xff0c;就为大家详细介绍三支一…

专题一四数之和

1.题目 题目分析&#xff1a; 给一个数组&#xff0c;在里面找到四个数字&#xff0c;满足四个数字之和等于给的特定值&#xff0c;四数之和可以拆分成三数之和&#xff0c;再继续拆分成二数之和&#xff0c;由简化繁。 2.算法原理 通过排序加双指针 1.依次固定一个数 2.在…

如何在docker中的mysql容器内执行命令与执行SQL文件

通过 docker ps -a 查询当前运行的容器&#xff0c;找到想执行命令的容器名称。 docker ps -a若想执行sql文件&#xff0c;则将sql文件放入当前文件夹下后将项目内的 SQL 文件拷贝到 mysql 容器内部的 root下。 sudo docker cp /root/enterprise.sql mysql:/root/然后进入 my…

Linux线程同步与互斥应用/生产者消费者模型

一&#xff0c;理论讲解 我们拿工厂&#xff0c;超市和消费者直接的关系来做讲解&#xff0c;首先人去超市买东西的过程就不用多说&#xff0c;但是超市本身是不能生产商品的&#xff0c;他们需要从各个不同的工厂进货商品&#xff0c;然后再给消费者买&#xff0c;以计算机的…

基于YOLO11深度学习的遥感视角农田检测与分割系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标分割、人工智能

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

RabbitMQ面试题及原理

RabbitMQ使用场景&#xff1a; 异步发送&#xff08;验证码、短信、邮件…&#xff09;MYSQL和Redis, ES之间的数据同步分布式事务削峰填谷 1. 消息可靠性&#xff08;不丢失&#xff09; 消息丢失场景&#xff1a; RabbitMQ-如何保证消息不丟失&#xff1f; 开启生产者确…

Python每日一练:学习指南进行汇总

Python&#xff0c;一种“优雅”、“明确”、“简单”的编程语言&#xff0c;凭借其低学习曲线、强大的开源生态系统、卓越的平台可移植性以及面向对象和函数式编程的支持&#xff0c;成为了众多开发者首选。 01 Python 应用领域和就业形势分析 Python&#xff0c;一种“优雅…

商米科技前端工程师(base上海)内推

1.根据原型或高保真设计&#xff0c;开发web、H5、小程序等类型的前端应用&#xff1b; 2.在指导下&#xff0c;高质量完成功能模块的开发&#xff0c;并负责各功能模块接口设计工作&#xff1b; 3.负责产品及相关支撑系统的开发及维护工作&#xff0c;不断的优化升级&#x…

八. Spring Boot2 整合连接 Redis(超详细剖析)

八. Spring Boot2 整合连接 Redis(超详细剖析) 文章目录 八. Spring Boot2 整合连接 Redis(超详细剖析)2. 注意事项和细节3. 最后&#xff1a; 在 springboot 中 , 整合 redis 可以通过 RedisTemplate 完成对 redis 的操作, 包括设置数据/获取数据 比如添加和读取数据 具体…

【漫话机器学习系列】113.逻辑回归(Logistic Regression) VS 线性回归(Linear Regression)

逻辑回归 vs 线性回归&#xff1a;详解对比 在机器学习和统计学中&#xff0c;逻辑回归&#xff08;Logistic Regression&#xff09; 和 线性回归&#xff08;Linear Regression&#xff09; 都是非常常见的模型。尽管它们的数学表达式有一定的相似性&#xff0c;但它们的应用…

构建智能 SQL 查询代理agent,把整个查询过程模块化,既能自动判断使用哪些表,又能自动生成 SQL 语句,最终返回查询结果

示例代码&#xff1a; import os import getpass from dotenv import load_dotenv from pyprojroot import here from typing import List from pprint import pprint from pydantic import BaseModel from langchain_core.tools import tool from langchain_core.runnables i…