Add tutorial explain how to use Mycelium in Rhai scripts
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				Rhai Tests / Run Rhai Tests (pull_request) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	Rhai Tests / Run Rhai Tests (pull_request) Has been cancelled
				
			This commit is contained in:
		
							
								
								
									
										332
									
								
								docs/docs/rhai/mycelium_tutorial.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										332
									
								
								docs/docs/rhai/mycelium_tutorial.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,332 @@
 | 
			
		||||
# Mycelium Tutorial for Rhai
 | 
			
		||||
 | 
			
		||||
This tutorial explains how to use the Mycelium networking functionality in Rhai scripts. Mycelium is a peer-to-peer networking system that allows nodes to communicate with each other, and the Rhai bindings provide an easy way to interact with Mycelium from your scripts.
 | 
			
		||||
 | 
			
		||||
## Introduction
 | 
			
		||||
 | 
			
		||||
The Mycelium module for Rhai provides the following capabilities:
 | 
			
		||||
 | 
			
		||||
- Getting node information
 | 
			
		||||
- Managing peers (listing, adding, removing)
 | 
			
		||||
- Viewing routing information
 | 
			
		||||
- Sending and receiving messages between nodes
 | 
			
		||||
 | 
			
		||||
This tutorial will walk you through using these features with example scripts.
 | 
			
		||||
 | 
			
		||||
## Prerequisites
 | 
			
		||||
 | 
			
		||||
Before using the Mycelium functionality in Rhai, you need:
 | 
			
		||||
 | 
			
		||||
1. A running Mycelium node accessible via HTTP
 | 
			
		||||
    > See https://github.com/threefoldtech/mycelium
 | 
			
		||||
2. The Rhai runtime with Mycelium module enabled
 | 
			
		||||
 | 
			
		||||
## Basic Mycelium Operations
 | 
			
		||||
 | 
			
		||||
Let's start by exploring the basic operations available in Mycelium using the `mycelium_basic.rhai` example.
 | 
			
		||||
 | 
			
		||||
### Getting Node Information
 | 
			
		||||
 | 
			
		||||
To get information about your Mycelium node:
 | 
			
		||||
 | 
			
		||||
```rhai
 | 
			
		||||
// API URL for Mycelium
 | 
			
		||||
let api_url = "http://localhost:8989";
 | 
			
		||||
 | 
			
		||||
// Get node information
 | 
			
		||||
print("Getting node information:");
 | 
			
		||||
try {
 | 
			
		||||
    let node_info = mycelium_get_node_info(api_url);
 | 
			
		||||
    print(`Node subnet: ${node_info.nodeSubnet}`);
 | 
			
		||||
    print(`Node public key: ${node_info.nodePubkey}`);
 | 
			
		||||
} catch(err) {
 | 
			
		||||
    print(`Error getting node info: ${err}`);
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This code:
 | 
			
		||||
1. Sets the API URL for your Mycelium node
 | 
			
		||||
2. Calls `mycelium_get_node_info()` to retrieve information about the node
 | 
			
		||||
3. Prints the node's subnet and public key
 | 
			
		||||
 | 
			
		||||
### Managing Peers
 | 
			
		||||
 | 
			
		||||
#### Listing Peers
 | 
			
		||||
 | 
			
		||||
To list all peers connected to your Mycelium node:
 | 
			
		||||
 | 
			
		||||
```rhai
 | 
			
		||||
// List all peers
 | 
			
		||||
print("\nListing all peers:");
 | 
			
		||||
try {
 | 
			
		||||
    let peers = mycelium_list_peers(api_url);
 | 
			
		||||
    
 | 
			
		||||
    if peers.is_empty() {
 | 
			
		||||
        print("No peers connected.");
 | 
			
		||||
    } else {
 | 
			
		||||
        for peer in peers {
 | 
			
		||||
            print(`Peer Endpoint: ${peer.endpoint.proto}://${peer.endpoint.socketAddr}`);
 | 
			
		||||
            print(`  Type: ${peer.type}`);
 | 
			
		||||
            print(`  Connection State: ${peer.connectionState}`);
 | 
			
		||||
            print(`  Bytes sent: ${peer.txBytes}`);
 | 
			
		||||
            print(`  Bytes received: ${peer.rxBytes}`);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
} catch(err) {
 | 
			
		||||
    print(`Error listing peers: ${err}`);
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This code:
 | 
			
		||||
1. Calls `mycelium_list_peers()` to get all connected peers
 | 
			
		||||
2. Iterates through the peers and prints their details
 | 
			
		||||
 | 
			
		||||
#### Adding a Peer
 | 
			
		||||
 | 
			
		||||
To add a new peer to your Mycelium node:
 | 
			
		||||
 | 
			
		||||
```rhai
 | 
			
		||||
// Add a new peer
 | 
			
		||||
print("\nAdding a new peer:");
 | 
			
		||||
let new_peer_address = "tcp://65.21.231.58:9651";
 | 
			
		||||
try {
 | 
			
		||||
    let result = mycelium_add_peer(api_url, new_peer_address);
 | 
			
		||||
    print(`Peer added: ${result.success}`);
 | 
			
		||||
} catch(err) {
 | 
			
		||||
    print(`Error adding peer: ${err}`);
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This code:
 | 
			
		||||
1. Specifies a peer address to add
 | 
			
		||||
2. Calls `mycelium_add_peer()` to add the peer to your node
 | 
			
		||||
3. Prints whether the operation was successful
 | 
			
		||||
 | 
			
		||||
#### Removing a Peer
 | 
			
		||||
 | 
			
		||||
To remove a peer from your Mycelium node:
 | 
			
		||||
 | 
			
		||||
```rhai
 | 
			
		||||
// Remove a peer
 | 
			
		||||
print("\nRemoving a peer:");
 | 
			
		||||
let peer_id = "tcp://65.21.231.58:9651"; // This is the peer we added earlier
 | 
			
		||||
try {
 | 
			
		||||
    let result = mycelium_remove_peer(api_url, peer_id);
 | 
			
		||||
    print(`Peer removed: ${result.success}`);
 | 
			
		||||
} catch(err) {
 | 
			
		||||
    print(`Error removing peer: ${err}`);
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This code:
 | 
			
		||||
1. Specifies the peer ID to remove
 | 
			
		||||
2. Calls `mycelium_remove_peer()` to remove the peer
 | 
			
		||||
3. Prints whether the operation was successful
 | 
			
		||||
 | 
			
		||||
### Viewing Routing Information
 | 
			
		||||
 | 
			
		||||
#### Listing Selected Routes
 | 
			
		||||
 | 
			
		||||
To list the selected routes in your Mycelium node:
 | 
			
		||||
 | 
			
		||||
```rhai
 | 
			
		||||
// List selected routes
 | 
			
		||||
print("\nListing selected routes:");
 | 
			
		||||
try {
 | 
			
		||||
    let routes = mycelium_list_selected_routes(api_url);
 | 
			
		||||
    
 | 
			
		||||
    if routes.is_empty() {
 | 
			
		||||
        print("No selected routes.");
 | 
			
		||||
    } else {
 | 
			
		||||
        for route in routes {
 | 
			
		||||
            print(`Subnet: ${route.subnet}`);
 | 
			
		||||
            print(`  Next hop: ${route.nextHop}`);
 | 
			
		||||
            print(`  Metric: ${route.metric}`);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
} catch(err) {
 | 
			
		||||
    print(`Error listing routes: ${err}`);
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This code:
 | 
			
		||||
1. Calls `mycelium_list_selected_routes()` to get all selected routes
 | 
			
		||||
2. Iterates through the routes and prints their details
 | 
			
		||||
 | 
			
		||||
#### Listing Fallback Routes
 | 
			
		||||
 | 
			
		||||
To list the fallback routes in your Mycelium node:
 | 
			
		||||
 | 
			
		||||
```rhai
 | 
			
		||||
// List fallback routes
 | 
			
		||||
print("\nListing fallback routes:");
 | 
			
		||||
try {
 | 
			
		||||
    let routes = mycelium_list_fallback_routes(api_url);
 | 
			
		||||
    
 | 
			
		||||
    if routes.is_empty() {
 | 
			
		||||
        print("No fallback routes.");
 | 
			
		||||
    } else {
 | 
			
		||||
        for route in routes {
 | 
			
		||||
            print(`Subnet: ${route.subnet}`);
 | 
			
		||||
            print(`  Next hop: ${route.nextHop}`);
 | 
			
		||||
            print(`  Metric: ${route.metric}`);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
} catch(err) {
 | 
			
		||||
    print(`Error listing fallback routes: ${err}`);
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This code:
 | 
			
		||||
1. Calls `mycelium_list_fallback_routes()` to get all fallback routes
 | 
			
		||||
2. Iterates through the routes and prints their details
 | 
			
		||||
 | 
			
		||||
## Sending Messages
 | 
			
		||||
 | 
			
		||||
Now let's look at how to send messages using the `mycelium_send_message.rhai` example.
 | 
			
		||||
 | 
			
		||||
```rhai
 | 
			
		||||
// API URL for Mycelium
 | 
			
		||||
let api_url = "http://localhost:1111";
 | 
			
		||||
 | 
			
		||||
// Send a message
 | 
			
		||||
print("\nSending a message:");
 | 
			
		||||
let destination = "5af:ae6b:dcd8:ffdb:b71:7dde:d3:1033"; // Replace with the actual destination IP address
 | 
			
		||||
let topic = "test_topic";
 | 
			
		||||
let message = "Hello from Rhai sender!";
 | 
			
		||||
let deadline_secs = -10; // Seconds we wait for a reply
 | 
			
		||||
 | 
			
		||||
try {
 | 
			
		||||
    print(`Attempting to send message to ${destination} on topic '${topic}'`);
 | 
			
		||||
    let result = mycelium_send_message(api_url, destination, topic, message, deadline_secs);
 | 
			
		||||
    print(`result: ${result}`);
 | 
			
		||||
    print(`Message sent: ${result.success}`);
 | 
			
		||||
    if result.id != "" {
 | 
			
		||||
        print(`Message ID: ${result.id}`);
 | 
			
		||||
    }
 | 
			
		||||
} catch(err) {
 | 
			
		||||
    print(`Error sending message: ${err}`);
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This code:
 | 
			
		||||
1. Sets the API URL for your Mycelium node
 | 
			
		||||
2. Specifies the destination IP address, topic, message content, and deadline
 | 
			
		||||
3. Calls `mycelium_send_message()` to send the message
 | 
			
		||||
4. Prints the result, including the message ID if successful
 | 
			
		||||
 | 
			
		||||
### Important Parameters for Sending Messages
 | 
			
		||||
 | 
			
		||||
- `api_url`: The URL of your Mycelium node's API
 | 
			
		||||
- `destination`: The IP address of the destination node
 | 
			
		||||
- `topic`: The topic to send the message on (must match what the receiver is listening for)
 | 
			
		||||
- `message`: The content of the message
 | 
			
		||||
- `deadline_secs`: Time in seconds to wait for a reply. Use a negative value if you don't want to wait for a reply.
 | 
			
		||||
 | 
			
		||||
## Receiving Messages
 | 
			
		||||
 | 
			
		||||
Now let's look at how to receive messages using the `mycelium_receive_message.rhai` example.
 | 
			
		||||
 | 
			
		||||
```rhai
 | 
			
		||||
// API URL for Mycelium
 | 
			
		||||
let api_url = "http://localhost:2222";
 | 
			
		||||
 | 
			
		||||
// Receive messages
 | 
			
		||||
print("\nReceiving messages:");
 | 
			
		||||
let receive_topic = "test_topic";
 | 
			
		||||
let wait_deadline_secs = 100; 
 | 
			
		||||
 | 
			
		||||
print(`Listening for messages on topic '${receive_topic}'...`);
 | 
			
		||||
try {
 | 
			
		||||
    let messages = mycelium_receive_messages(api_url, receive_topic, wait_deadline_secs);
 | 
			
		||||
    
 | 
			
		||||
    if messages.is_empty() {
 | 
			
		||||
        // print("No new messages received in this poll.");
 | 
			
		||||
    } else {
 | 
			
		||||
        print("Received a message:");
 | 
			
		||||
        print(`  Message id: ${messages.id}`);
 | 
			
		||||
        print(`  Message from: ${messages.srcIp}`);
 | 
			
		||||
        print(`  Topic: ${messages.topic}`);
 | 
			
		||||
        print(`  Payload: ${messages.payload}`);
 | 
			
		||||
    }
 | 
			
		||||
} catch(err) {
 | 
			
		||||
    print(`Error receiving messages: ${err}`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
print("Finished attempting to receive messages.");
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This code:
 | 
			
		||||
1. Sets the API URL for your Mycelium node
 | 
			
		||||
2. Specifies the topic to listen on and how long to wait for messages
 | 
			
		||||
3. Calls `mycelium_receive_messages()` to receive messages
 | 
			
		||||
4. Processes and prints any received messages
 | 
			
		||||
 | 
			
		||||
### Important Parameters for Receiving Messages
 | 
			
		||||
 | 
			
		||||
- `api_url`: The URL of your Mycelium node's API
 | 
			
		||||
- `receive_topic`: The topic to listen for messages on (must match what the sender is using)
 | 
			
		||||
- `wait_deadline_secs`: Time in seconds to wait for messages to arrive. The function will block for this duration if no messages are immediately available.
 | 
			
		||||
 | 
			
		||||
## Complete Messaging Example
 | 
			
		||||
 | 
			
		||||
To set up a complete messaging system, you would typically run two instances of Mycelium (node A sender, node B receiver).
 | 
			
		||||
 | 
			
		||||
1. Run the `mycelium_receive_message.rhai` script to listen for messages. **Fill in the API address of node B**.
 | 
			
		||||
2. Run the `mycelium_send_message.rhai` script to send messages. **Fill in the API address of node A, and fill in the overlay address of node B as destination**.
 | 
			
		||||
 | 
			
		||||
### Setting Up the Receiver
 | 
			
		||||
 | 
			
		||||
First, start a Mycelium node and run the receiver script:
 | 
			
		||||
 | 
			
		||||
```rhai
 | 
			
		||||
// API URL for Mycelium
 | 
			
		||||
let api_url = "http://localhost:2222";  // Your receiver node's API URL
 | 
			
		||||
 | 
			
		||||
// Receive messages
 | 
			
		||||
let receive_topic = "test_topic";
 | 
			
		||||
let wait_deadline_secs = 100;  // Wait up to 100 seconds for messages
 | 
			
		||||
 | 
			
		||||
print(`Listening for messages on topic '${receive_topic}'...`);
 | 
			
		||||
try {
 | 
			
		||||
    let messages = mycelium_receive_messages(api_url, receive_topic, wait_deadline_secs);
 | 
			
		||||
    
 | 
			
		||||
    if messages.is_empty() {
 | 
			
		||||
        print("No new messages received in this poll.");
 | 
			
		||||
    } else {
 | 
			
		||||
        print("Received a message:");
 | 
			
		||||
        print(`  Message id: ${messages.id}`);
 | 
			
		||||
        print(`  Message from: ${messages.srcIp}`);
 | 
			
		||||
        print(`  Topic: ${messages.topic}`);
 | 
			
		||||
        print(`  Payload: ${messages.payload}`);
 | 
			
		||||
    }
 | 
			
		||||
} catch(err) {
 | 
			
		||||
    print(`Error receiving messages: ${err}`);
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Setting Up the Sender
 | 
			
		||||
 | 
			
		||||
Then, on another Mycelium node, run the sender script:
 | 
			
		||||
 | 
			
		||||
```rhai
 | 
			
		||||
// API URL for Mycelium
 | 
			
		||||
let api_url = "http://localhost:1111";  // Your sender node's API URL
 | 
			
		||||
 | 
			
		||||
// Send a message
 | 
			
		||||
let destination = "5af:ae6b:dcd8:ffdb:b71:7dde:d3:1033";  // The receiver node's IP address
 | 
			
		||||
let topic = "test_topic";  // Must match the receiver's topic
 | 
			
		||||
let message = "Hello from Rhai sender!";
 | 
			
		||||
let deadline_secs = -10;  // Don't wait for a reply
 | 
			
		||||
 | 
			
		||||
try {
 | 
			
		||||
    print(`Attempting to send message to ${destination} on topic '${topic}'`);
 | 
			
		||||
    let result = mycelium_send_message(api_url, destination, topic, message, deadline_secs);
 | 
			
		||||
    print(`Message sent: ${result.success}`);
 | 
			
		||||
    if result.id != "" {
 | 
			
		||||
        print(`Message ID: ${result.id}`);
 | 
			
		||||
    }
 | 
			
		||||
} catch(err) {
 | 
			
		||||
    print(`Error sending message: ${err}`);
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
		Reference in New Issue
	
	Block a user