Refactor AIS server to use Axum framework with shared stream manager and state handling. Fix metadata key mismatch in frontend vessel mapper.

This commit is contained in:
geoffsee
2025-07-21 18:05:41 -04:00
parent 0a0c15a47e
commit b4c80f3e01
5 changed files with 345 additions and 405 deletions

1
Cargo.lock generated
View File

@@ -132,6 +132,7 @@ dependencies = [
"tokio",
"tokio-test",
"tokio-tungstenite 0.20.1",
"tokio-util",
"tower 0.4.13",
"tower-http 0.5.2",
"url",

View File

@@ -62,7 +62,7 @@ const convertAisResponseToVesselData = (aisResponse: AisResponse): VesselData |
}
return {
id: aisResponse.mmsi ?? !aisResponse.raw_message?.MetaData?.MSSI,
id: aisResponse.mmsi ?? aisResponse.raw_message?.MetaData?.MMSI,
name: aisResponse.ship_name || `Vessel ${aisResponse.mmsi}`,
type: aisResponse.ship_type || 'Unknown',
latitude: aisResponse.latitude,
@@ -71,7 +71,7 @@ const convertAisResponseToVesselData = (aisResponse: AisResponse): VesselData |
speed: aisResponse.speed_over_ground || 0,
length: 100, // Default length
width: 20, // Default width
mmsi: aisResponse.mmsi,
mmsi: aisResponse.mmsi ?? aisResponse.raw_message?.MetaData?.MMSI,
callSign: '',
destination: '',
eta: '',
@@ -338,8 +338,8 @@ export const useAISProvider = (boundingBox?: BoundingBox) => {
console.log('Updated bounding box:', bbox);
// Clear existing vessels when bounding box changes
vesselMapRef.current.clear();
setVessels([]);
// vesselMapRef.current.clear();
// setVessels([]);
}
}, []);

View File

@@ -14,6 +14,7 @@ axum = { version = "0.7", features = ["ws"] }
tower = "0.4"
tower-http = { version = "0.5", features = ["cors"] }
base64 = "0.22.1"
tokio-util = "0.7.15"
[dev-dependencies]
tokio-test = "0.4"

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,36 @@
use crate::ais::start_ais_server;
use std::sync::Arc;
use axum::Router;
use axum::routing::get;
use tower_http::cors::CorsLayer;
use crate::ais::{AisStreamManager, AppState};
mod ais;
#[tokio::main]
async fn main() {
if let Err(e) = start_ais_server().await {
eprintln!("Server error: {:?}", e);
}
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create the shared state with the AIS stream manager
let state = AppState {
ais_stream_manager: Arc::new(AisStreamManager::new()),
};
// Create and start the Axum HTTP server
let app = create_router(state);
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?;
println!("AIS server running on http://0.0.0.0:3000");
axum::serve(listener, app)
.with_graceful_shutdown(ais::shutdown_signal())
.await?;
Ok(())
}
// Create the Axum router
fn create_router(state: AppState) -> Router {
Router::new()
.route("/ais", get(crate::ais::get_ais_data))
.route("/ws", get(crate::ais::websocket_handler))
.layer(CorsLayer::permissive())
.with_state(state)
}