mirror of
https://github.com/go-i2p/go-sam-go.git
synced 2025-12-01 09:54:58 -05:00
Refactor ExampleDatagramSession to improve error handling and simplify datagram sending/receiving logic; enhance output messages for better clarity.
This commit is contained in:
109
datagram_test.go
109
datagram_test.go
@@ -88,111 +88,74 @@ func Test_DatagramServerClient(t *testing.T) {
|
||||
|
||||
func ExampleDatagramSession() {
|
||||
// Creates a new DatagramSession, which behaves just like a net.PacketConn.
|
||||
// Note: This example requires a running I2P router with SAM bridge enabled.
|
||||
// If no I2P router is available, the example will print an error and return.
|
||||
// This example demonstrates I2P datagram communication by sending messages
|
||||
// and attempting to receive them through the I2P network.
|
||||
//
|
||||
// Requirements: This example requires a running I2P router with SAM bridge enabled.
|
||||
|
||||
const samBridge = "127.0.0.1:7656"
|
||||
|
||||
sam, err := NewSAM(samBridge)
|
||||
if err != nil {
|
||||
fmt.Println("Error creating SAM connection (I2P router may not be running):", err.Error())
|
||||
fmt.Printf("Failed to connect to I2P SAM bridge at %s: %v\n", samBridge, err)
|
||||
return
|
||||
}
|
||||
defer sam.Close()
|
||||
|
||||
keys, err := sam.NewKeys()
|
||||
if err != nil {
|
||||
fmt.Println("Error generating keys:", err.Error())
|
||||
sam.Close()
|
||||
fmt.Printf("Failed to generate I2P keys: %v\n", err)
|
||||
return
|
||||
}
|
||||
myself := keys.Addr()
|
||||
|
||||
// See the example Option_* variables.
|
||||
// Create datagram session with small tunnel configuration for faster setup
|
||||
dg, err := sam.NewDatagramSession("DGTUN", keys, Options_Small, 0)
|
||||
if err != nil {
|
||||
fmt.Println("Error creating datagram session:", err.Error())
|
||||
sam.Close()
|
||||
fmt.Printf("Failed to create datagram session: %v\n", err)
|
||||
return
|
||||
}
|
||||
defer dg.Close()
|
||||
|
||||
// Try to lookup a destination (this may fail if I2P is not fully started)
|
||||
someone, err := sam.Lookup("zzz.i2p")
|
||||
if err != nil {
|
||||
fmt.Println("Warning: Could not resolve zzz.i2p (I2P may still be starting up):", err.Error())
|
||||
// Use a placeholder address for demonstration
|
||||
someone = myself
|
||||
}
|
||||
|
||||
// Send datagrams (these operations may timeout if I2P tunnels are not ready)
|
||||
// For this example, we'll send messages to ourselves to demonstrate functionality
|
||||
fmt.Println("Sending datagrams...")
|
||||
|
||||
// Use timeouts for I2P operations
|
||||
sendTimeout := make(chan bool, 1)
|
||||
go func() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
fmt.Printf("Error during send operation: %v\n", r)
|
||||
}
|
||||
sendTimeout <- true
|
||||
}()
|
||||
|
||||
_, err1 := dg.WriteTo([]byte("Hello stranger!"), someone)
|
||||
if err1 != nil {
|
||||
fmt.Println("Warning: Could not send to destination:", err1.Error())
|
||||
}
|
||||
|
||||
_, err2 := dg.WriteTo([]byte("Hello myself!"), myself)
|
||||
if err2 != nil {
|
||||
fmt.Println("Warning: Could not send to self:", err2.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
// Wait for send operations with timeout
|
||||
select {
|
||||
case <-sendTimeout:
|
||||
// Sends completed (successfully or with errors)
|
||||
case <-time.After(30 * time.Second):
|
||||
fmt.Println("Warning: Send operations timed out (I2P tunnels may not be ready)")
|
||||
// Send a message to ourselves (this should work if I2P tunnels are established)
|
||||
_, err = dg.WriteTo([]byte("Hello myself!"), myself)
|
||||
if err != nil {
|
||||
dg.Close()
|
||||
sam.Close()
|
||||
fmt.Printf("Failed to send datagram: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Try to receive a datagram with reasonable timeout
|
||||
fmt.Println("Attempting to receive datagram...")
|
||||
receiveTimeout := make(chan bool, 1)
|
||||
var received bool
|
||||
|
||||
go func() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
fmt.Printf("Error during receive operation: %v\n", r)
|
||||
}
|
||||
receiveTimeout <- true
|
||||
}()
|
||||
// Set a reasonable deadline for the receive operation (I2P operations need time)
|
||||
dg.SetReadDeadline(time.Now().Add(60 * time.Second))
|
||||
|
||||
buf := make([]byte, 31*1024)
|
||||
n, _, err := dg.ReadFrom(buf)
|
||||
if err != nil {
|
||||
fmt.Println("Could not receive datagram:", err.Error())
|
||||
} else {
|
||||
fmt.Printf("Got message: %s\n", string(buf[:n]))
|
||||
received = true
|
||||
}
|
||||
}()
|
||||
|
||||
// Wait for receive operation with timeout
|
||||
select {
|
||||
case <-receiveTimeout:
|
||||
if !received {
|
||||
fmt.Println("No datagram received (this is normal if I2P tunnels are not fully established)")
|
||||
}
|
||||
case <-time.After(30 * time.Second):
|
||||
fmt.Println("Receive operation timed out (normal behavior when no messages are available)")
|
||||
buf := make([]byte, 31*1024)
|
||||
n, addr, err := dg.ReadFrom(buf)
|
||||
if err != nil {
|
||||
dg.Close()
|
||||
sam.Close()
|
||||
fmt.Printf("Failed to receive datagram within 60 seconds: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("Received message: %s\n", string(buf[:n]))
|
||||
fmt.Printf("From address: %s\n", addr.String())
|
||||
|
||||
// Clean up resources
|
||||
dg.Close()
|
||||
sam.Close()
|
||||
|
||||
fmt.Println("DatagramSession example completed")
|
||||
return
|
||||
|
||||
// Output:
|
||||
// Sending datagrams...
|
||||
// Attempting to receive datagram...
|
||||
// Received message: Hello myself!
|
||||
// From address: [I2P address]
|
||||
// DatagramSession example completed
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user