译者 | 布加迪
审校 | 重楼
51CTO读者成长计划社群招募,咨询小助手(微信号:TTalkxiaozhuli)
HTTP利用客户端/服务器架构来传输信息和数据。Rust等服务器端编程语言的特性之一是,开发用于与基于HTTP的服务交互的服务器和客户端应用程序。
Rust因其安全性、性能和可靠性等特性而适合构建HTTP服务器系统。Rust的第三方库(比如Actix和Rocket)因构建能够处理高流量的复杂Web服务器而大受欢迎。
Rust在Web服务器开发方面大受欢迎,因为该语言的一些特性正是构建大多数Web服务器所需要的。
使用Rust可以确保应用程序有效扩展,使该语言成为构建高性能应用程序的理想语言。以下是考虑为Web服务器及其他服务器端应用程序使用Rust的几个具体原因。
高性能是Rust成为构建HTTP Web服务器绝佳选择的原因之一。Rust提供了对系统资源(包括内存和CPU)的低级访问,使您能够编写比其他服务器端语言使用更少资源运行得更快的代码。
此外,Rust的所有权机制不需要编译时收集垃圾,这是一些服务器端语言速度较慢的原因之一。
Rust的内存管理所有权机制使得该语言对于Web服务器开发而言很安全。您不会遇到可能导致内存泄漏及其他安全漏洞的空指针或悬空指针引用。
Rust的所有权机制可以防止这些常见错误,为您的服务器和应用程序确保安全。Rust还专注于防止缓冲区溢出及其他与内存相关的错误。
并发性是指能够以无序的方式运行程序的多个单元而不影响输出。并发程序的输出应该与异步程序的输出相同。
并发性会显著影响应用程序的性能,因为服务器需要同时处理多个请求。Rust支持与轻量级线程模型共存。
Rust中并发编程的优势在于,所有权机制让您可以编写线程安全的代码,不需要锁及其他同步原语。
Rust标准库和Rust生态系统中的第三方软件包为有效的Web服务器开发提供了现代工具。
Rust的软件包管理器Cargo简化了依赖项管理和构建流程。此外,Rust还通过Rust Analyzer等工具提供了出色的IDE支持,这类工具提供了无缝代码补全、错误高亮显示及其他特性。
Rust的标准库拥有构建Web服务器所需的大部分实用程序。像Rocket和Actix这样的第三方库简化了用Rust服务器端应用程序的工作。
Actix和Rocket是流行的Rust Web框架,但它们的库在设计和特性上有所不同。
Rocket是一种高级Web框架,注重生产力和易用性。Rocket为使用Rust构建Web应用程序提供了大量的抽象和语法元素。Rocket也因其强大的类型和直观的API设计而颇受欢迎。
您可以在Cargo.toml文件中添加Rocket作为项目依赖项,从而开始使用Rust构建Web应用程序:
[dependencies]
rocket = "0.4.11"
另一方面,Actix-web是一个注重性能和可扩展性的低级框架。Actix利用了基于actor的并发模型,提供了非阻塞I/O,这使得该软件包成为构建高性能Web应用程序的理想选择。
在Cargo.toml文件的依赖项部分中添加Actix作为项目依赖项:
[dependencies]
actix-web = "4.3.1"
为项目选择一个库将取决于您项目的规范、库的特性以及您在使用Rust和HTTP方面的经验。
在创建Rust项目并将任何Rocket或Actix框架添加到Cargo.toml文件中的项目依赖项之后,您已准备好开始使用Rust构建Web服务器了。

使用Rust构建Web服务时,您可以为请求使用序列化器。
Serde是一个流行的Rust库,用于在Rust类型与JSON、YAML和TOML等数据格式之间序列化和反序列化数据。Serde提供了一个框架,用于定义Rust数据结构与其他数据格式的对应表示之间的数据转换。
下面是为您的项目添加Serde作为第三方软件包的指令。
[dependencies]
serde = { version = "1.0.159" , features = ["derive"] }
一旦您添加了Serde和Actix作为项目依赖项,就可以用Rust生成基本的Web服务器。下面介绍了如何创建一个简单的Hello World! Web服务器,使用Actix将字符串写入到客户端:
首先,从actix_web库和serde库导入必要的模块和类型:
use actix_web::{get, web, App, HttpResponse, HttpServer, Responder};
use serde::{Deserialize, Serialize};
您将使用serde用构件(struct)将消息序列化到客户端。serde将为客户端将构件转换成JSON。下面是该消息的构件:
#[derive(Debug, Serialize, Deserialize)]
struct Message {
message: String,
}
现在您可以为端点定义处理程序(handler)函数。在处理程序函数的顶部,您可以为自定义行为添加装饰符:
#[get("/")]
async fn hello() -> impl Responder {
HttpResponse::Ok().json(Message {
message: "Hello, World!".to_owned(),
})
}
hello处理程序函数处理GET请求。该函数返回实现来自Actix软件包的Responder特征的类型。
HttpResponse::Ok()类型的JSON方法接受Serde在底层处理的构件实例,并将响应返回给客户端。
定义端点后,您可以启动服务器实例,并将端点挂载到路由上。
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new().service(hello))
.bind("127.0.0.1:8080")?
.run()
.await
}
HttpServer::new函数是一个新的服务器实例。main函数启动,服务器用新的应用程序实例挂载hello处理程序函数。bind方法将服务器绑定到指定的URL,run函数运行服务器。

Rocket很简约,所以您可以构建简单的Web服务器,无需任何依赖项(除了Rocket库外)。
下面介绍如何使用Rocket创建带有Hello World!端点的简单服务器:
首先,为服务器导入必要的依赖项。
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use]
extern crate rocket;
// imports from the Rocket crate
use rocket::response::content;
use rocket::State;
#![feature(proc_macro_hygiene, decl_macro)]属性为Rocket框架启用了Rust实验特性。#[macro_use]属性从Rocket模块导入宏。
下面是一个处理程序函数,接到请求时提供HTML:
#[get("/")]
fn hello_world() -> content::Html<&'static str> {
content::Html("<h1>Hello, world!</h1>")
}
hello_world函数返回一个HTML静态字符串,含有content:: HTML函数。
下面是服务器的配置构件声明(Rocket框架约定):
struct Config {
port: u16,
}
#[get("/port")]
fn port(config: State<Config>) -> String {
format!("Server running on port {}", config.port)
}
运行服务器时,可以向/port端点请求端口状态。
最后,您将使用ignite函数创建一个服务器实例。添加配置、挂载路由,并启动服务器:
fn main() {
let config = Config { port: 8000 };
rocket::ignite()
.manage(config)
.mount("/", routes![hello_world, port])
.launch();
}
config变量是config构件的一个实例。ignite函数启动服务器实例,manage方法为服务器添加配置,mount方法在基本路由上挂载处理程序函数。最后,launch方法启动服务器以侦听指定的端口。
WebAssembly(WASM)是一种二进制指令格式,是为了在浏览器及其他设备上执行而设计的。WASM提供了一种低级字节码格式,Rust等高级编程语言可以将其用作编译目标。
借助WASM,您可以将Rust代码编译成大多数流行浏览器都可以执行的二进制格式。WASM为使用Rust构建健壮的Web应用程序(包括全栈Web应用程序)提供了无限的可能。
原文链接:https://www.makeuseof.com/build-http-web-server-in-rust/

我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t