This document provides examples of how to use the vpnclient_engine_flutter library with the new instance-based API.
The library now supports both static and instance-based usage patterns. Here's how to use the new instance-based approach:
class VpnState extends StatefulWidget {
@override
_VpnStateState createState() => _VpnStateState();
}
class _VpnStateState extends State<VpnState> {
late VpnclientEngineFlutter _vpnEngine;
ConnectionStatus _currentStatus = ConnectionStatus.disconnected;
@override
void initState() {
super.initState();
_initializeVpnEngine();
}
void _initializeVpnEngine() {
// Initialize VPN client engine with status callback
_vpnEngine = VpnclientEngineFlutter(
onStatusChanged: (status) {
setState(() {
_currentStatus = status;
});
print('VPN Status changed to: $status');
},
);
// Initialize the engine
_vpnEngine.initialize();
}
@override
void dispose() {
_vpnEngine.dispose();
super.dispose();
}
// ... rest of your widget implementation
}Future<void> _connectToServer() async {
try {
// Example configuration
const config = '''
{
"inbounds": [
{
"port": 1080,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
}
],
"outbounds": [
{
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "your-server.com",
"port": 443,
"users": [
{
"id": "your-uuid-here",
"alterId": 0
}
]
}
]
}
}
]
}
''';
final success = await _vpnEngine.connect(EngineType.libxray, config);
if (success) {
print('Connection initiated successfully');
} else {
print('Failed to initiate connection');
}
} catch (e) {
print('Error connecting: $e');
}
}Future<void> _disconnect() async {
try {
await _vpnEngine.disconnect();
print('Disconnected successfully');
} catch (e) {
print('Error disconnecting: $e');
}
}Future<void> _testConfiguration(String config) async {
try {
final isValid = await _vpnEngine.testConfig(EngineType.libxray, config);
if (isValid) {
print('Configuration is valid');
} else {
print('Configuration is invalid');
}
} catch (e) {
print('Error testing configuration: $e');
}
}Future<void> _pingServer(String config) async {
try {
final latency = await _vpnEngine.ping(
EngineType.libxray,
config,
'https://www.google.com',
timeout: 10,
);
if (latency >= 0) {
print('Ping: ${latency}ms');
} else {
print('Ping failed');
}
} catch (e) {
print('Error pinging: $e');
}
}void _getEngineInfo() {
// Get current engine type
final currentEngine = _vpnEngine.getCurrentEngineType();
print('Current engine: ${currentEngine?.name ?? 'None'}');
// Get supported engines
final supportedEngines = VpnclientEngineFlutter.getSupportedEngines();
print('Supported engines: $supportedEngines');
// Check if specific engine is supported
final isLibXraySupported = VpnclientEngineFlutter.isEngineSupported(EngineType.libxray);
print('LibXray supported: $isLibXraySupported');
}void _setStatusCallback() {
_vpnEngine.setStatusCallback((status) {
print('Status changed to: $status');
// Handle status change
});
}The library supports the following VPN engines:
EngineType.libxray- LibXray engineEngineType.singbox- SingBox engineEngineType.v2ray- V2Ray engine
The library provides the following connection statuses:
ConnectionStatus.disconnected- Not connectedConnectionStatus.connecting- Connecting in progressConnectionStatus.connected- Successfully connectedConnectionStatus.error- Connection error
- iOS/macOS: All engines supported
- Android: All engines supported
- Other platforms: Limited support
The library maintains backward compatibility with the static API. You can still use:
// Static methods (legacy)
await VpnclientEngineFlutter.initialize();
await VpnclientEngineFlutter.connect(EngineType.libxray, config);
await VpnclientEngineFlutter.disconnect();See the example/lib/vpn_state_example.dart file for a complete working example that demonstrates all the features of the new API.
Always wrap VPN operations in try-catch blocks to handle potential errors:
try {
await _vpnEngine.connect(EngineType.libxray, config);
} catch (e) {
print('VPN operation failed: $e');
// Handle error appropriately
}Remember to dispose of the VPN engine when you're done:
@override
void dispose() {
_vpnEngine.dispose();
super.dispose();
}This ensures that any background timers or resources are properly cleaned up.