wukong_easy_sdk 1.0.1
wukong_easy_sdk: ^1.0.1 copied to clipboard
A lightweight Flutter SDK for WuKongIM that enables real-time chat functionality in 5 minutes.
WuKong Easy SDK for Flutter #
A lightweight, easy-to-use Flutter SDK for WuKongIM that enables real-time messaging functionality in your Flutter applications within minutes.
✨ Features #
- 🚀 Quick Integration: Get started in under 5 minutes
- 🔄 Auto Reconnection: Built-in intelligent reconnection with exponential backoff
- 📱 Cross Platform: Works seamlessly on iOS, Android, Web, and Desktop
- 🎯 Type Safe: Full Dart type safety with null safety support
- 🔧 Easy to Use: Simple and intuitive API design
- 📦 Lightweight: Minimal dependencies (only 2 external packages)
- 🎨 Event-Driven: Reactive programming with event listeners
- 🔐 Secure: WebSocket with authentication support
- 📊 Real-time: Instant message delivery and status updates
📋 Requirements #
- Flutter 3.0.0 or higher
- Dart 3.0.0 or higher
- A running WuKongIM server
📦 Installation #
Add this to your package's pubspec.yaml
file:
dependencies:
wukong_easy_sdk: ^1.0.0
Then run:
flutter pub get
🚀 Quick Start #
Step 1: Import the SDK #
import 'package:wukong_easy_sdk/wukong_easy_sdk.dart';
Step 2: Initialize the SDK #
// Create configuration
final config = WuKongConfig(
serverUrl: "ws://your-wukongim-server.com:5200", // Your WuKongIM server URL
uid: "user123", // Unique user identifier
token: "your_auth_token", // Authentication token
deviceId: "device_001", // Optional: Device identifier
deviceFlag: WuKongDeviceFlag.app, // Optional: Device type (app/web)
);
// Get SDK instance and initialize
final easySDK = WuKongEasySDK.getInstance();
await easySDK.init(config);
Step 3: Set up Event Listeners #
// Listen for connection events
easySDK.addEventListener(WuKongEvent.connect, (ConnectResult result) {
print("✅ Connected successfully!");
print("Server version: ${result.serverVersion}");
print("Time difference: ${result.timeDiff}ms");
});
easySDK.addEventListener(WuKongEvent.disconnect, (DisconnectInfo info) {
print("❌ Disconnected: ${info.reason} (Code: ${info.code})");
});
// Listen for incoming messages
easySDK.addEventListener(WuKongEvent.message, (Message message) {
print("📨 New message from ${message.fromUid}:");
print("Content: ${message.payload}");
print("Channel: ${message.channelId}");
});
// Listen for errors
easySDK.addEventListener(WuKongEvent.error, (WuKongError error) {
print("🚨 Error: ${error.message}");
});
Step 4: Connect to Server #
try {
await easySDK.connect();
print("🎉 Connected to WuKongIM server!");
} catch (e) {
print("💥 Connection failed: $e");
// Handle connection error
}
Step 5: Send Messages #
// Create message payload
final messagePayload = {
"type": 1, // Message type (1 = text)
"content": "Hello from Flutter!", // Message content
"timestamp": DateTime.now().millisecondsSinceEpoch,
};
try {
final result = await easySDK.send(
channelId: "friend_user_id", // Target user/channel ID
channelType: WuKongChannelType.person, // Channel type (person/group)
payload: messagePayload, // Message data
);
print("✅ Message sent successfully!");
print("Message ID: ${result.messageId}");
print("Message Sequence: ${result.messageSeq}");
} catch (e) {
print("❌ Failed to send message: $e");
}
Step 6: Clean Up (Important!) #
@override
void dispose() {
// Remove event listeners
easySDK.removeEventListener(WuKongEvent.connect, connectListener);
easySDK.removeEventListener(WuKongEvent.message, messageListener);
// Disconnect and dispose
easySDK.disconnect();
easySDK.dispose();
super.dispose();
}
📚 Usage #
Complete Example #
Here's a complete example of integrating WuKong Easy SDK in a Flutter app:
import 'package:flutter/material.dart';
import 'package:wukong_easy_sdk/wukong_easy_sdk.dart';
class ChatPage extends StatefulWidget {
@override
_ChatPageState createState() => _ChatPageState();
}
class _ChatPageState extends State<ChatPage> {
late WuKongEasySDK easySDK;
bool isConnected = false;
List<String> messages = [];
// Event listener references
WuKongEventListener<ConnectResult>? connectListener;
WuKongEventListener<Message>? messageListener;
WuKongEventListener<DisconnectInfo>? disconnectListener;
@override
void initState() {
super.initState();
_initializeSDK();
}
Future<void> _initializeSDK() async {
easySDK = WuKongEasySDK.getInstance();
// Configure SDK
final config = WuKongConfig(
serverUrl: "ws://localhost:5200",
uid: "flutter_user",
token: "your_token_here",
);
await easySDK.init(config);
_setupEventListeners();
// Connect to server
try {
await easySDK.connect();
} catch (e) {
print("Connection failed: $e");
}
}
void _setupEventListeners() {
connectListener = (ConnectResult result) {
setState(() {
isConnected = true;
});
_addMessage("Connected to server!");
};
messageListener = (Message message) {
_addMessage("${message.fromUid}: ${message.payload}");
};
disconnectListener = (DisconnectInfo info) {
setState(() {
isConnected = false;
});
_addMessage("Disconnected: ${info.reason}");
};
easySDK.addEventListener(WuKongEvent.connect, connectListener!);
easySDK.addEventListener(WuKongEvent.message, messageListener!);
easySDK.addEventListener(WuKongEvent.disconnect, disconnectListener!);
}
void _addMessage(String message) {
setState(() {
messages.add(message);
});
}
Future<void> _sendMessage(String content) async {
if (!isConnected) return;
try {
await easySDK.send(
channelId: "test_channel",
channelType: WuKongChannelType.person,
payload: {"type": 1, "content": content},
);
_addMessage("You: $content");
} catch (e) {
_addMessage("Failed to send: $e");
}
}
@override
void dispose() {
// Clean up event listeners
if (connectListener != null) {
easySDK.removeEventListener(WuKongEvent.connect, connectListener!);
}
if (messageListener != null) {
easySDK.removeEventListener(WuKongEvent.message, messageListener!);
}
if (disconnectListener != null) {
easySDK.removeEventListener(WuKongEvent.disconnect, disconnectListener!);
}
easySDK.disconnect();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('WuKong Chat'),
backgroundColor: isConnected ? Colors.green : Colors.red,
),
body: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: messages.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(messages[index]),
);
},
),
),
Padding(
padding: EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: TextField(
onSubmitted: _sendMessage,
decoration: InputDecoration(
hintText: 'Type a message...',
),
),
),
],
),
),
],
),
);
}
}
📖 API Reference #
WuKongEasySDK #
The main SDK class implementing the singleton pattern.
Static Methods
Method | Description | Returns |
---|---|---|
getInstance() |
Get the singleton SDK instance | WuKongEasySDK |
Instance Methods
Method | Parameters | Description | Returns |
---|---|---|---|
init(config) |
WuKongConfig config |
Initialize SDK with configuration | Future<void> |
connect() |
None | Connect to WuKongIM server | Future<void> |
disconnect() |
None | Disconnect from server | void |
send() |
See Send Parameters | Send a message | Future<SendResult> |
addEventListener() |
WuKongEvent event, Function listener |
Add event listener | void |
removeEventListener() |
WuKongEvent event, Function listener |
Remove event listener | void |
dispose() |
None | Clean up all resources | void |
Properties
Property | Type | Description |
---|---|---|
isConnected |
bool |
Whether connected to server |
isConnecting |
bool |
Whether currently connecting |
isInitialized |
bool |
Whether SDK is initialized |
Send Parameters
Future<SendResult> send({
required String channelId, // Target channel/user ID
required WuKongChannelType channelType, // Channel type
required dynamic payload, // Message payload
String? clientMsgNo, // Optional: Client message number
Map<String, dynamic>? header, // Optional: Message headers
String? topic, // Optional: Message topic
dynamic setting, // Optional: Message settings
})
Events #
Event | Trigger | Data Type |
---|---|---|
WuKongEvent.connect |
Connection established | ConnectResult |
WuKongEvent.disconnect |
Connection lost | DisconnectInfo |
WuKongEvent.message |
Message received | Message |
WuKongEvent.error |
Error occurred | WuKongError |
Channel Types #
Type | Value | Description |
---|---|---|
WuKongChannelType.person |
1 | 1-on-1 private chat |
WuKongChannelType.group |
2 | Group chat |
Data Models #
ConnectResult
class ConnectResult {
final String? serverKey; // Server encryption key (optional)
final String? salt; // Encryption salt (optional)
final int timeDiff; // Time difference with server (ms)
final int reasonCode; // Connection reason code
final int? serverVersion; // Server version (optional)
final int? nodeId; // Server node ID (optional)
}
Message
class Message {
final String messageId; // Unique message ID
final int messageSeq; // Message sequence number
final String fromUid; // Sender user ID
final String channelId; // Channel/conversation ID
final int channelType; // Channel type
final dynamic payload; // Message content
final int timestamp; // Message timestamp
final MessageHeader header; // Message headers
}
SendResult
class SendResult {
final String messageId; // Generated message ID
final int messageSeq; // Message sequence number
}
🚨 Error Handling #
The SDK provides specific exception types for different error scenarios:
try {
await easySDK.send(
channelId: "user123",
channelType: WuKongChannelType.person,
payload: {"type": 1, "content": "Hello!"},
);
} catch (e) {
if (e is WuKongNotConnectedException) {
print("❌ Not connected to server");
// Show connection error to user
} else if (e is WuKongConfigurationException) {
print("⚙️ Configuration error: ${e.message}");
// Fix configuration issues
} else if (e is WuKongProtocolException) {
print("🔌 Protocol error: ${e.message}");
// Handle protocol-level errors
} else if (e is WuKongNetworkException) {
print("🌐 Network error: ${e.message}");
// Handle network connectivity issues
} else if (e is WuKongAuthenticationException) {
print("🔐 Authentication failed: ${e.message}");
// Handle authentication errors
} else if (e is WuKongConnectionTimeoutException) {
print("⏰ Connection timeout: ${e.message}");
// Handle timeout scenarios
} else {
print("💥 Unexpected error: $e");
// Handle other errors
}
}
💡 Best Practices #
1. Event Listener Management #
Always store references to your event listeners for proper cleanup:
class _ChatPageState extends State<ChatPage> {
late WuKongEasySDK easySDK;
WuKongEventListener<Message>? messageListener;
WuKongEventListener<ConnectResult>? connectListener;
@override
void initState() {
super.initState();
easySDK = WuKongEasySDK.getInstance();
_setupListeners();
}
void _setupListeners() {
messageListener = (Message message) {
if (mounted) {
setState(() {
// Handle message safely
});
}
};
connectListener = (ConnectResult result) {
if (mounted) {
// Handle connection
}
};
easySDK.addEventListener(WuKongEvent.message, messageListener!);
easySDK.addEventListener(WuKongEvent.connect, connectListener!);
}
@override
void dispose() {
// Always clean up listeners
if (messageListener != null) {
easySDK.removeEventListener(WuKongEvent.message, messageListener!);
}
if (connectListener != null) {
easySDK.removeEventListener(WuKongEvent.connect, connectListener!);
}
super.dispose();
}
}
2. Connection State Management #
class ConnectionManager {
static bool _isConnected = false;
static bool get isConnected => _isConnected;
static Future<void> ensureConnection() async {
final sdk = WuKongEasySDK.getInstance();
if (!sdk.isConnected) {
try {
await sdk.connect();
_isConnected = true;
} catch (e) {
_isConnected = false;
throw e;
}
}
}
static Future<void> sendMessage(String channelId, dynamic payload) async {
await ensureConnection();
final sdk = WuKongEasySDK.getInstance();
await sdk.send(
channelId: channelId,
channelType: WuKongChannelType.person,
payload: payload,
);
}
}
3. Message Payload Structure #
// Recommended message payload structure
final messagePayload = {
"type": 1, // Message type (1=text, 2=image, etc.)
"content": "Hello, World!", // Message content
"timestamp": DateTime.now().millisecondsSinceEpoch,
"extra": { // Optional extra data
"mentions": ["user123"], // Mentioned users
"reply_to": "message_id_123", // Reply to message
}
};
📱 Example Application #
This SDK includes a complete example application demonstrating all features:
cd example
flutter run
The example app includes:
- ✅ Connection management with visual status
- ✅ Real-time messaging interface
- ✅ Event logging and debugging
- ✅ Error handling demonstrations
- ✅ Modern Material Design 3 UI
🔧 Development #
Running Tests #
flutter test
Code Analysis #
flutter analyze
Building Documentation #
dart doc
🌍 Platform Support #
Platform | Status | Notes |
---|---|---|
Android | ✅ Supported | Android 5.0+ (API 21+) |
iOS | ✅ Supported | iOS 11.0+ |
Web | ✅ Supported | Modern browsers with WebSocket support |
macOS | ✅ Supported | macOS 10.14+ |
Windows | ✅ Supported | Windows 10+ |
Linux | ✅ Supported | Modern Linux distributions |
📄 License #
This project is licensed under the MIT License - see the LICENSE file for details.
🤝 Contributing #
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature
) - Commit your changes (
git commit -m 'Add some AmazingFeature'
) - Push to the branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
📞 Support #
- 📖 Documentation: API Reference
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
- 🌐 WuKongIM: Official Website
📊 Changelog #
See CHANGELOG.md for a detailed list of changes and version history.
Made with ❤️ by the WuKongIM team