Найти в Дзене
Один Rust не п...Rust

Rust + React = mobile app

t.me/oneRustnoqRust Для чего нужна данная статья? : - Получить представление о разработке React и Rust. - Найти компромисс между использованием библиотеки Rust в качестве собственного модуля или WebAssembly. Узнать что такое: Зачем Вам это уметь? : Архитектура: Пример (Rust API): // Actix-web API
use actix_web::{get, web, App, HttpResponse, HttpServer, Responder};
#[get("/api/data")]
async fn get_data() -> impl Responder {
HttpResponse::Ok().json(serde_json::json!({"message": "From Rust!"}))
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new().service(get_data))
.bind("127.0.0.1:8080")?
.run()
.await
} React Fetch: function App() {
const [data, setData] = useState();
useEffect(() => {
fetch("http://localhost:8080/api/data")
.then(res => res.json())
.then(setData);
}, []);
return <div>{data?.message}</div>;
} Использование: Пример (Rust WASM): // src/lib.rs
use wasm_bindgen::prelude::*;
Оглавление
GitHub - nicktretyakov/Rust_React_Streem
ML на RUST без заморочек

t.me/oneRustnoqRust

Для чего нужна данная статья? :

- Получить представление о разработке React и Rust.

- Найти компромисс между использованием библиотеки Rust в качестве собственного модуля или WebAssembly.

Узнать что такое:

  1. Реальная обработка видео потока с камеры
  2. Многомодельная ML-система:
    YOLOv8 для обнаружения объектов
    ResNet-50 для классификации
    NLP модель для анализа текста
  3. Распределенная обработка данных
  4. JWT аутентификация с OAuth2
  5. Оптимизированные WASM-модули для предобработки данных

Зачем Вам это уметь? :

1. Backend API + React Frontend

Архитектура:

  • Rust (Actix-web/Rocket) → REST/GraphQL API
  • React → SPA Frontend

Пример (Rust API):

// Actix-web API
use actix_web::{get, web, App, HttpResponse, HttpServer, Responder};

#[get("/api/data")]
async fn get_data() -> impl Responder {
HttpResponse::Ok().json(serde_json::json!({"message": "From Rust!"}))
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new().service(get_data))
.bind("127.0.0.1:8080")?
.run()
.await
}

React Fetch:

function App() {
const [data, setData] = useState();

useEffect(() => {
fetch("http://localhost:8080/api/data")
.then(res => res.json())
.then(setData);
}, []);

return <div>{data?.message}</div>;
}

2. WebAssembly (WASM) в React

Использование:

  • Вычисления в браузере
  • Обработка изображений/аудио
  • Криптография

Пример (Rust WASM):

// src/lib.rs
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn fibonacci(n: u32) -> u32 {
match n {
0 => 0,
1 => 1,
_ => fibonacci(n-1) + fibonacci(n-2),
}
}

React Integration:

import init, { fibonacci } from './wasm/pkg/wasm.js';

function App() {
const [result, setResult] = useState<number>();

useEffect(() => {
init().then(() => {
setResult(fibonacci(10));
});
}, []);

return <div>Fibonacci(10): {result}</div>;
}

3. Desktop Apps (Tauri)

Стек:

  • Rust (Tauri Core)
  • React (UI)
  • SQLite (Встроенная БД)

Пример Tauri Command:

#[tauri::command]
fn read_file(path: String) -> Result<String, String> {
std::fs::read_to_string(path)
.map_err(|e| e.to_string())
}

React Вызов:

import { invoke } from '@tauri-apps/api';

function FileReader() {
const readFile = async () => {
const content = await invoke('read_file', { path: './data.txt' });
console.log(content);
};

return <button onClick={readFile}>Read File</button>;
}

4. CLI Tools для React Dev

Сценарии:

  • Генерация компонентов
  • Анализ производительности
  • Конвертация форматов

Пример CLI на Rust:

// Генератор компонентов
use clap::Parser;

#[derive(Parser)]
struct Cli {
component: String,
}

fn main() {
let args = Cli::parse();
let content = format!(
"export const {} = () => <div>New Component</div>",
args.component
);
std::fs::write(format!("./src/{}.tsx", args.component), content).unwrap();
}

5. Game Dev (WebAssembly + WebGL)

Архитектура:

  • Rust: Игровое ядро (Bevy Engine)
  • React: UI Overlay
  • WebGL: Рендеринг

Пример Bevy System:

fn movement_system(
mut query: Query<(&mut Transform, &Velocity)>,
time: Res<Time>
) {
for (mut transform, velocity) in query.iter_mut() {
transform.translation += velocity.0 * time.delta_seconds();
}
}

React UI Integration:

const GameUI = ({ score }) => (
<div className="overlay">
<HealthBar />
<Score value={score} />
</div>
);

6. Blockchain (Smart Contracts + dApps)

Стек:

  • Rust: Solana/Polkadot контракты
  • React: dApp Frontend
  • Web3.js/ethers.js

Пример Anchor Program:

#[program]
mod my_program {
use super::*;

pub fn initialize(ctx: Context<Initialize>, data: u64) -> Result<()> {
ctx.accounts.my_account.data = data;
Ok(())
}
}

React Wallet Integration:

const ConnectButton = () => {
const connect = useWallet().connect;

return (
<button onClick={connect}>
Connect Solana Wallet
</button>
);
};

7. Real-Time Systems (WebSockets)

Архитектура:

  • Rust: WebSocket Server (tokio-tungstenite)
  • React: WebSocket Client

Rust Server:

async fn handle_connection(stream: TcpStream) {
let ws_stream = tokio_tungstenite::accept_async(stream).await.unwrap();
while let Some(msg) = ws_stream.next().await {
// Обработка сообщений
}
}

React Client:

const RealTimeFeed = () => {
const [messages, setMessages] = useState([]);
const ws = useRef(new WebSocket('ws://localhost:8080'));

useEffect(() => {
ws.current.onmessage = (e) => {
setMessages(prev => [...prev, e.data]);
};
}, []);

return <div>{messages.join('\n')}</div>;
};

8. Cross-Platform Mobile (React Native)

Интеграция:

  • Rust: Нативные модули (JSI)
  • React Native: UI

Пример Native Module:

#[no_mangle]
pub extern "C" fn native_add(a: i32, b: i32) -> i32 {
a + b
}

React Native Binding:

import { NativeModules } from 'react-native';

const { RustModule } = NativeModules;

const App = () => (
<Text>
Result: {RustModule.native_add(2, 3)}
</Text>
);

9. Machine Learning Inference

Сценарий:

  • Rust: Сервер для инференса (ONNX)
  • React: Визуализация результатов

Пример ML API:

async fn predict(
bytes: web::Bytes,
model: web::Data<Arc<ort::Session>>
) -> Result<Json<Value>> {
let input = preprocess(bytes);
let outputs = model.run(input)?;
Ok(Json(outputs))
}

React Upload:

const ModelUploader = () => {
const [file, setFile] = useState<File>();

const predict = async () => {
const formData = new FormData();
formData.append('file', file);
const res = await axios.post('/api/predict', formData);
// Визуализация
};
return <input type="file" onChange={e => setFile(e.target.files[0])} />;
};

10. Static Site Generation (SSG)

Архитектура:

  • Rust: Генератор контента (Markdown → JSON)
  • React: Gatsby/Next.js

Пример генератора:

fn generate_content(path: &Path) -> Result<()> {
let content = std::fs::read_to_string(path)?;
let html = markdown::to_html(&content);
let json = serde_json::to_string(&Frontmatter::parse(&content))?;
write_output(path, json, html)
}

Настройка среды разработки:

установите необходимые инструменты и библиотеки для React Native, вам нужно будет установить Node.js, React Native CLI и эмулятор или устройство Android или iOS.

Добавить поддержку Rust:

Вы можете использовать библиотеку Rust в качестве собственного модуля в своем приложении или скомпилировать код Rust в WebAssembly и использовать его в своем приложении. Если вы выберете первый вариант, вам нужно будет использовать менеджер пакетов Rust Cargo для создания библиотеки Rust, а затем использовать библиотеку мостов, такую как FFI, для вызова функций Rust из вашего приложения. Если вы выберете второй вариант, вам нужно будет использовать такой инструмент, как wasm-pack, для компиляции кода Rust в WebAssembly, а затем использовать библиотеку JavaScript, такую как wasm-bindgen, для вызова функций Rust из вашего приложения.

Что может понадобиться?:

wasm-pack: инструмент командной строки для сборки и публикации модулей WebAssembly, сгенерированных Rust. Он поставляется со встроенной поддержкой упаковки модулей в виде пакетов NPM, что упрощает их использование в проектах JavaScript.

cargo-web: подкоманда Cargo, которая может быть использована для создания кода Rust в WebAssembly и других целевых форматах, таких как JavaScript или собственные двоичные файлы. Он поддерживает цели wasm32-unknown-unknown и wasm32-unknown-emscripten.

wasm-bindgen: библиотека Rust, которая позволяет легко взаимодействовать между Rust и JavaScript. Он генерирует клеевой код, необходимый для вызова функций Rust из JavaScript и наоборот. wasm-bindgen также предоставляет такие функции, как автоматическое управление памятью и преобразование типов.

wargo: инструмент, который позволяет создавать модули WebAssembly из кода Rust с помощью Cargo. Он предназначен для упрощения процесса создания и публикации модулей WebAssembly и включает в себя такие функции, как автоматическая комплектация и оптимизация.

stdweb: библиотека Rust, предоставляющая набор API для взаимодействия с моделью DOM и другими веб-API. Он позволяет писать веб-приложения полностью на Rust, без необходимости Использования JavaScript. stdweb можно использовать для создания модулей WebAssembly или кода JavaScript.

wasm-micro-runtime: облегченная среда выполнения для WebAssembly, которая может быть встроена в приложения, написанные на C или Rust. Он предназначен для использования в средах с ограниченными ресурсами, таких как микроконтроллеры или устройства IoT.

wasm-opt: инструмент, который считывает WebAssembly в качестве входных данных, выполняет преобразование, оптимизацию, передает его, а затем выдает преобразованную WebAssembly в качестве выхода.

wasm2js: Инструмент, который компилирует WebAssembly в "almost asm.js".

wasm-gc: Небольшой инструмент для сбора мусора модуля WebAssembly и удаления всех ненужных экспортов, импортов, функций.

wasm-snip: инструмент, который заменяет тело функции WebAssembly недоступной инструкцией.

Создание API Rust:

используйте менеджер пакетов Cargo для создания нового проекта Rust. Вы можете использовать команду cargo new myapp для создания нового проекта с именем "myapp".

Пример:

$ cargo new notes-app --bin

Добавление зависимостей Cargo.toml:

[dependencies]

rocket = "0.5.0-rc.1"

serde = { version = "1.0", features = ["derive"] }

Создание REST API с использованием Rocket для CRUD операций:

#[derive(Debug, Serialize, Deserialize)]

struct Note {

id: u64,

title: String,

content: String, }

#[get("/notes")] fn get_notes() -> Json<Vec<Note>> {
// TODO: Implement getting all notes from the database }

#[get("/notes/<id>")] fn get_note(id: u64) -> Option<Json<Note>> {
// TODO: Implement getting a single note by ID from the database }

#[post("/notes", data = "<note>")] fn create_note(note: Json<Note>) -> Json<Note> {
// TODO: Implement creating a new note in the database }

#[put("/notes/<id>", data = "<note>")] fn update_note(id: u64, note: Json<Note>) -> Option<Json<Note>> {
// TODO: Implement updating a note by ID in the database }

#[delete("/notes/<id>")] fn delete_note(id: u64) -> Option<()> {
// TODO: Implement deleting a note by ID from the database }

#[launch] fn rocket() -> _ {

rocket::build()

.mount("/", routes![get_notes, get_note, create_note, update_note,

delete_note])

}

Создание нового проекта React:

используйте инструмент create-react-app для создания нового проекта React. Вы можете использовать команду npx create-react-app myapp для создания нового проекта с именем "myapp".

Пример:

import React, { useState, useEffect } from 'react';

import { StyleSheet, Text, View, TextInput, Button } from 'react-native';

export default function App() {

const [notes, setNotes] = useState([]);

useEffect(() => {

fetch('http://localhost:8000/notes')

.then(response => response.json())

.then(data => setNotes(data))

.catch(error => console.error(error));

},

[]);

const [title, setTitle] = useState('');

const [content, setContent] = useState('');

const handleSubmit = () => {

fetch('http://localhost:8000/notes', {

method: 'POST',

headers: { 'Content-Type': 'application/json' },

body: JSON.stringify({ title, content })

})

.then(response => response.json())

.then(data => setNotes([...notes, data]))

.catch(error => console.error(error));

setTitle('');

setContent('');

};

return (

<View style={styles.container}>

<Text style={styles.title}>Notes</Text>

{notes.map(note => (

<View key={note.id} style={styles.note}>

<Text style={styles.noteTitle}>{note.title}</Text>

<Text style={styles.noteContent}>{note.content}</Text>

</View>

))}

<TextInput

style={styles.input}

placeholder="Title"

value={title}

onChangeText={setTitle}

/>

<TextInput

style={styles.input}

placeholder="Content"

value={content}

onChangeText={setContent} />

Добавление поддержки Rust в React:

используйте инструмент wasm-pack для создания модуля WebAssembly из кода Rust. Вы можете использовать команду wasm-pack init --scope myusername для создания нового проекта Rust для WebAssembly. Затем используйте команду wasm-pack build --target web для сборки кода Rust в качестве модуля WebAssembly.

Загрузка кода Rust в React:

используйте библиотеку react-rust-wasm для загрузки модуля WebAssembly в приложение React. Вы можете использовать хук useRust для загрузки модуля и вызова функций Rust из компонентов React.

Интеграция кода Rust:

используйте библиотеку Rust или модуль WebAssembly, созданный ранее, чтобы добавить дополнительные функции в приложение.

Cоздание простого мобильного приложения

1.1 Создайте новый Rust-проект:

cargo new rust_library

cd rust_library

1.2 Напишите код на Rust:

Файл src/lib.rs:

#[no_mangle] pub extern "C"

fn add_numbers(a: i32, b: i32) -> i32

{ a + b }

Здесь #[no_mangle] говорит Rust компилятору не изменять имя функции, чтобы она была доступна для вызова из других языков, таких как JavaScript или C/C++.

1.3 Скомпилируйте Rust-код в статическую библиотеку:

Для Android:

cargo build --target aarch64-linux-android --release

Для iOS:

cargo build --target aarch64-apple-ios --release

2.1 Установите React Native CLI и создайте проект:

npx react-native init RustReactApp

cd RustReactApp

2.2 Интеграция с Rust через Native Modules

Для интеграции Rust в React Native мы используем нативные модули (Native Modules).

2.2.1 Android (Java):

Создайте RustModule.java в android/app/src/main/java/com/rustreactapp/:

package com.rustreactapp;

import com.facebook.react.bridge.ReactApplicationContext;

import com.facebook.react.bridge.ReactContextBaseJavaModule;

import com.facebook.react.bridge.ReactMethod;

import com.facebook.react.bridge.Callback;

public class RustModule extends ReactContextBaseJavaModule {

static {

System.loadLibrary("rust_library");

}

private native int addNumbers(int a, int b);

RustModule(ReactApplicationContext context) {

super(context);

}


@Override

public String getName() {

return "RustModule";

}

@ReactMethod

public void add(int a, int b, Callback callback) {

int result = addNumbers(a, b);

callback.invoke(result);

}

}

2.2.2 iOS (Objective-C):

Создайте RustModule.m в ios/RustReactApp/:

#import <React/RCTBridgeModule.h>

@interface RCT_EXTERN_MODULE(RustModule, NSObject)

RCT_EXTERN_METHOD(add:(NSInteger)a b:(NSInteger)b callback:

(RCTResponseSenderBlock)callback)

@end

Затем создайте RustModule.swift:

import Foundation

@objc(RustModule)

class RustModule: NSObject {

@objc(add:b:callback:)

func add(a: Int, b: Int, callback: RCTResponseSenderBlock) {

let result = add_numbers(Int32(a), Int32(b))

callback([NSNull(), Int(result)])

}

}
Не забудьте добавить библиотеку Rust в настройки Xcode, чтобы она была включена в сборку iOS.

3.1 Создайте простое приложение:

Файл App.js:

import React, { useState } from 'react';

import { Button, Text, View } from 'react-native';

import { NativeModules } from 'react-native';

const { RustModule } = NativeModules;

const App = () => {

const [result, setResult] = useState(null);

const handleAdd = () => {

RustModule.add(5, 3, (res) => {

setResult(res);

});

};

return (

<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>

<Button title="Add 5 + 3" onPress={handleAdd} />

{result !== null && <Text>Result: {result}</Text>}

</View>

);

};

export default App;
Теперь вы можете запустить ваше приложение на Android или iOS:

npx react-native run-android

npx react-native run-ios


Real-Time Threat Detection System (RTTDS)

Архитектура:

  1. Frontend: React + TypeScript + WebAssembly + Redux Toolkit + WebSocket
  2. Backend:
    Rust (Actix-Web) + Tokio + Diesel + PostgreSQL
    Python ML Microservice (FastAPI + PyTorch + OpenCV + Transformers)
  3. Инфраструктура:
    Docker + Kubernetes
    Kafka для потоковой обработки
    Prometheus + Grafana для мониторинга

// backend/src/main.rs (Rust API Gateway)

#[actix_web::main]

async fn main() -> std::io::Result<()> {

use actix_web::{web, App, HttpServer};

use diesel::{r2d2::ConnectionManager, PgConnection};

type DbPool = r2d2::Pool<ConnectionManager<PgConnection>>;

let manager = ConnectionManager::<PgConnection>::new(

std::env::var("DATABASE_URL").unwrap()

);

let pool = r2d2::Pool::builder()

.build(manager)

.unwrap();

HttpServer::new(move || {

App::new()

.app_data(web::Data::new(pool.clone()))

.service(web::resource("/analyze")

.route(web::post().to(analyze_handler))

.service(web::resource("/ws")

.route(web::get().to(websocket_handler)))

})

.bind("0.0.0.0:8080")?

.run()

.await

}

async fn analyze_handler(

stream: web::Payload,

pool: web::Data<DbPool>,

) -> Result<HttpResponse, Error> {

// Обработка медиапотока и взаимодействие с ML сервисом

}

ML Service (Python):

# ml_api/main.py

from fastapi import FastAPI, File

import torch

from transformers import pipeline

app = FastAPI()

@app.post("/detect")

async def detect_objects(data: bytes = File(...)):

model = torch.hub.load('ultralytics/yolov8', 'yolov8s')

results = model(data)

return results.pandas().xyxy[0].to_dict()

Интеграция React+WASM:

// frontend/src/components/VideoProcessor.tsx

import init, { process_frame } from '../wasm/lib.rs';

const VideoStream: FC = () => {

const processVideo = async (frame: VideoFrame) => {

await init();

const processed = process_frame(new Uint8Array(frame.data));

// Отправка на сервер через WebSocket

};

return (

<WebSocket url="ws://localhost:8080/ws">

{({ send }) => (

<VideoRecorder onFrame={processVideo} />

)}

</WebSocket>

);

};