{"id":21577828,"url":"https://github.com/foxzool/bevy_mqtt","last_synced_at":"2025-07-18T11:10:03.477Z","repository":{"id":229990769,"uuid":"778168554","full_name":"foxzool/bevy_mqtt","owner":"foxzool","description":"A MQTT client Plugin for Bevy game engine","archived":false,"fork":false,"pushed_at":"2024-12-09T05:48:22.000Z","size":55,"stargazers_count":10,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-24T15:11:14.091Z","etag":null,"topics":["bevy-engine","ecs","mqtt","mqtt-client"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/foxzool.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-27T07:59:57.000Z","updated_at":"2025-02-24T17:27:53.000Z","dependencies_parsed_at":null,"dependency_job_id":"c0c1db51-c651-4df1-bcc8-34328742c756","html_url":"https://github.com/foxzool/bevy_mqtt","commit_stats":null,"previous_names":["foxzool/bevy_mqtt"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foxzool%2Fbevy_mqtt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foxzool%2Fbevy_mqtt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foxzool%2Fbevy_mqtt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foxzool%2Fbevy_mqtt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/foxzool","download_url":"https://codeload.github.com/foxzool/bevy_mqtt/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248261983,"owners_count":21074229,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bevy-engine","ecs","mqtt","mqtt-client"],"created_at":"2024-11-24T13:08:44.263Z","updated_at":"2025-07-18T11:10:03.450Z","avatar_url":"https://github.com/foxzool.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bevy_mqtt\n\n[![crates.io](https://img.shields.io/crates/v/bevy_mqtt)](https://crates.io/crates/bevy_mqtt)\n[![MIT/Apache 2.0](https://img.shields.io/badge/license-MIT%2FApache-blue.svg)](https://github.com/Seldom-SE/seldom_pixel#license)\n[![crates.io](https://img.shields.io/crates/d/bevy_mqtt)](https://crates.io/crates/bevy_mqtt)\n[![CI](https://github.com/foxzool/bevy_mqtt/workflows/CI/badge.svg)](https://github.com/foxzool/bevy_mqtt/actions)\n[![Documentation](https://docs.rs/bevy_mqtt/badge.svg)](https://docs.rs/bevy_mqtt)\n\nA robust, secure MQTT client plugin for the Bevy game engine with comprehensive error handling and performance\noptimizations.\n\n## Features\n\n- 🔌 **Easy Integration** - Simple plugin architecture that fits naturally into Bevy's ECS\n- 🔒 **Security First** - Regex injection protection and robust error handling\n- ⚡ **High Performance** - Optimized message dispatch with memory reuse patterns\n- 🌐 **Multiple Transports** - Support for TCP and WebSocket connections\n- 📦 **Message Caching** - Built-in packet caching with configurable capacity limits\n- 🎯 **Topic Matching** - MQTT wildcard support with secure regex pattern matching\n- 🔄 **Auto Reconnection** - Automatic reconnection handling on connection failures\n- 📊 **Event-Driven** - Full integration with Bevy's event system\n\n## Quick Start\n\nFirst, run an MQTT broker like [Mosquitto](https://mosquitto.org/):\n\n```bash\n# Using Docker\ndocker run -it -p 1883:1883 -p 9001:9001 eclipse-mosquitto:2\n\n# Or using docker-compose (see docker-compose.yml in this repo)\ndocker-compose up\n```\n\nThen add bevy_mqtt to your `Cargo.toml`:\n\n```toml\n[dependencies]\nbevy_mqtt = \"0.7.1\"\n```\n\n## Basic Example\n\n```rust\nuse bevy::{prelude::*, time::common_conditions::on_timer};\nuse bevy_mqtt::{\n    MqttClient, MqttClientConnected, MqttClientError, MqttConnectError, MqttEvent,\n    MqttPlugin, MqttPublishOutgoing, MqttSetting, SubscribeTopic, TopicMessage,\n};\nuse rumqttc::{MqttOptions, QoS};\nuse std::time::Duration;\n\nfn main() {\n    App::new()\n        .add_plugins((DefaultPlugins, MqttPlugin))\n        .add_systems(Startup, setup_mqtt_client)\n        .add_systems(Update, (\n            subscribe_to_topics,\n            handle_messages,\n            handle_errors,\n            publish_messages.run_if(on_timer(Duration::from_secs(5))),\n        ))\n        .run();\n}\n\nfn setup_mqtt_client(mut commands: Commands) {\n    // TCP connection\n    commands.spawn(MqttSetting {\n        mqtt_options: MqttOptions::new(\"bevy-game-client\", \"localhost\", 1883),\n        cap: 100, // Channel capacity\n    });\n}\n\nfn subscribe_to_topics(\n    mut commands: Commands,\n    mqtt_clients: Query\u003cEntity, Added\u003cMqttClientConnected\u003e\u003e,\n) {\n    for client_entity in mqtt_clients.iter() {\n        // Subscribe using component-based approach with MQTT wildcards\n        let topic_entity = commands\n            .spawn(SubscribeTopic::new(\"game/+/events\", QoS::AtMostOnce).unwrap())\n            .observe(|trigger: Trigger\u003cTopicMessage\u003e| {\n                println!(\"Game event: {}\", trigger.event().topic);\n            })\n            .id();\n\n        // Link topic subscription to client\n        commands.entity(client_entity).add_child(topic_entity);\n    }\n}\n\nfn handle_messages(mut mqtt_events: EventReader\u003cMqttEvent\u003e) {\n    for event in mqtt_events.read() {\n        if let rumqttc::Event::Incoming(rumqttc::Incoming::Publish(publish)) = \u0026event.event {\n            println!(\"Received on {}: {:?}\", publish.topic, publish.payload);\n        }\n    }\n}\n\nfn handle_errors(\n    mut connect_errors: EventReader\u003cMqttConnectError\u003e,\n    mut client_errors: EventReader\u003cMqttClientError\u003e,\n) {\n    for error in connect_errors.read() {\n        eprintln!(\"MQTT connection error: {:?}\", error.error);\n    }\n\n    for error in client_errors.read() {\n        eprintln!(\"MQTT client error: {:?}\", error.error);\n    }\n}\n\n// Event-driven publishing (recommended)\nfn publish_messages(\n    mqtt_clients: Query\u003cEntity, With\u003cMqttClientConnected\u003e\u003e,\n    mut publish_events: EventWriter\u003cMqttPublishOutgoing\u003e,\n) {\n    for client_entity in mqtt_clients.iter() {\n        publish_events.send(MqttPublishOutgoing {\n            entity: client_entity,\n            topic: \"game/player/position\".to_string(),\n            qos: QoS::AtLeastOnce,\n            retain: false,\n            payload: b\"x:100,y:200\".to_vec(),\n        });\n    }\n}\n```\n\n## Advanced Features\n\n### Message Caching\n\n```rust\nuse bevy_mqtt::PacketCache;\n\n// Add message caching to topic subscriptions\ncommands\n.spawn((\nSubscribeTopic::new(\"game/chat\", QoS::AtMostOnce).unwrap(),\nPacketCache::new(50), // Keep last 50 messages\n))\n.observe( | trigger: Trigger\u003cTopicMessage\u003e| {\nprintln ! (\"Chat message: {:?}\", trigger.event().payload);\n});\n```\n\n### WebSocket Support\n\n```rust\nuse rumqttc::Transport;\n\nlet mut mqtt_options = MqttOptions::new(\"websocket-client\", \"ws://localhost:9001\", 9001);\nmqtt_options.set_transport(Transport::Ws);\n\ncommands.spawn(MqttSetting {\nmqtt_options,\ncap: 100,\n});\n```\n\n### Secure Topic Patterns\n\nThe library automatically escapes regex metacharacters in topic patterns while preserving MQTT wildcards:\n\n```rust\n// Safe - regex metacharacters are escaped, MQTT wildcards preserved\nSubscribeTopic::new(\"sensor/data[temp]/+\", QoS::AtMostOnce).unwrap();\n\n// This matches: \"sensor/data[temp]/kitchen\" but not \"sensor/dataXtemp]/kitchen\"\n```\n\n## Supported Versions\n\n| bevy | bevy_mqtt     |\n|------|---------------|\n| 0.16 | 0.7.1         |\n| 0.16 | 0.7, 0.6      |\n| 0.15 | 0.5           |\n| 0.14 | 0.2, 0.3, 0.4 |\n| 0.13 | 0.1           |\n\n## License\n\nDual-licensed under either:\n\n- [`MIT`](LICENSE-MIT): [http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT)\n- [\n  `Apache 2.0`](LICENSE-APACHE): [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)\n\nAt your option. This means that when using this crate in your game, you may choose which license to use.\n\nUnless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as\ndefined in the Apache-2.0 license, shall be dually licensed as above, without any additional terms or conditions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffoxzool%2Fbevy_mqtt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffoxzool%2Fbevy_mqtt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffoxzool%2Fbevy_mqtt/lists"}