PixeltooSocket
Современная Socket.IO библиотека для Flutter, созданная с нуля для обеспечения надежного real-time соединения с серверами Socket.IO.
Особенности
- ✅ Полная совместимость с Socket.IO v4
- 🚀 Умная эскалация транспортов с автоматическим переключением
- 📋 Настраиваемый порядок транспортов (WebSocket ↔ Polling)
- ⚡ Rate Limiting для защиты от спама запросов
- 🔄 Автоматическое переподключение
- 📈 Статистика производительности транспортов
- ⏱️ Поддержка событий с подтверждением (acknowledgments)
- 🎯 Настраиваемые опции подключения
- 📝 Подробное логирование
- 🎛️ Типобезопасные события
- 🔐 Поддержка HTTP заголовков и query параметров
- 🏠 Система комнат (rooms)
- 🧪 Обработка ошибок и таймаутов
Установка
Добавьте в pubspec.yaml:
dependencies:
pixeltoo_socket: ^0.1.0
Быстрый старт
import 'package:pixeltoo_socket/pixeltoo_socket.dart';
void main() async {
// Создание клиента
final socket = io('http://localhost:3000');
// Подписка на события
socket.on('connect', (data) {
print('Подключен!');
socket.emit('hello', 'Привет от Flutter!');
});
socket.on('message', (data) {
print('Получено: $data');
});
// Подключение происходит автоматически
// Или можно подключиться вручную:
// await socket.connect();
}
Основное API
Создание клиента
// Простое подключение
final socket = io('http://localhost:3000');
// С настройками
final socket = io('http://localhost:3000',
timeout: 10000,
autoConnect: false,
reconnectionAttempts: 3,
enableLogging: true,
headers: {'Authorization': 'Bearer token'},
query: {'userId': '123'},
);
Управление подключением
// Подключение
await socket.connect();
// Отключение
socket.disconnect();
// Проверка состояния
if (socket.isConnected) {
print('Подключен');
}
// Получение текущего состояния
print(socket.state); // SocketIOConnectionState
События
// Подписка на событие
socket.on('message', (data) {
print('Сообщение: $data');
});
// Подписка на событие (один раз)
socket.once('welcome', (data) {
print('Добро пожаловать: $data');
});
// Отписка от события
socket.off('message');
// Отписка конкретного обработчика
void handler(data) => print(data);
socket.on('test', handler);
socket.off('test', handler);
// Очистка всех обработчиков
socket.clearAllHandlers();
Отправка событий
// Простая отправка
socket.emit('message', 'Привет!');
// Отправка объекта
socket.emit('user_data', {
'name': 'Иван',
'age': 25,
});
// Отправка с подтверждением
try {
final response = await socket.emitWithAck('get_data', {'id': 123});
print('Ответ: $response');
} catch (e) {
print('Таймаут или ошибка: $e');
}
Системные события
socket.on('connect', (data) {
print('Подключен к серверу');
});
socket.on('disconnect', (data) {
print('Отключен от сервера');
});
socket.on('error', (error) {
print('Ошибка: $error');
});
🚀 Новые возможности v0.1.0
Умная эскалация транспортов
Автоматическое переключение между WebSocket и Polling на основе производительности:
final socket = io('http://localhost:3000',
transportType: SocketIOTransportType.auto,
transportOrder: ["websocket", "polling"], // Порядок попыток
enableTransportEscalation: true,
transportEscalationInterval: 10000, // Проверка каждые 10 секунд
);
// Получение текущего транспорта
print('Текущий транспорт: ${socket.currentTransportType}');
// Статистика производительности
final stats = socket.getTransportStats();
stats.forEach((transport, data) {
print('$transport: ${data['errorRate']}% ошибок, ${data['averageLatency']}ms задержка');
});
Rate Limiting
Защита от спама запросов с настраиваемыми лимитами:
final socket = io('http://localhost:3000',
rateLimitInterval: 100, // Минимум 100ms между запросами
maxRequestsPerMinute: 300, // Максимум 300 запросов в минуту
);
// Библиотека автоматически контролирует частоту запросов
for (int i = 0; i < 100; i++) {
socket.emit('message', 'Сообщение $i'); // Автоматический rate limiting
}
Настраиваемый порядок транспортов
Выбор приоритета транспортов в зависимости от условий:
// Приоритет Polling (для нестабильных сетей)
final socket = io('http://localhost:3000',
transportOrder: ["polling", "websocket"],
);
// Приоритет WebSocket (для быстрых сетей)
final socket = io('http://localhost:3000',
transportOrder: ["websocket", "polling"],
);
// Только один транспорт
final socket = io('http://localhost:3000',
transportType: SocketIOTransportType.polling, // Только polling
);
Настройки подключения
SocketIOOptions
const options = SocketIOOptions(
url: 'http://localhost:3000', // URL сервера
transportType: SocketIOTransportType.auto, // Тип транспорта
transportOrder: ["websocket", "polling"], // Порядок транспортов
timeout: 20000, // Таймаут подключения (мс)
autoConnect: true, // Автоподключение
reconnectionDelay: 1000, // Задержка переподключения (мс)
reconnectionAttempts: 5, // Количество попыток
rateLimitInterval: 100, // Минимальный интервал между запросами (мс)
maxRequestsPerMinute: 300, // Максимум запросов в минуту
transportEscalationInterval: 10000, // Интервал проверки эскалации (мс)
enableTransportEscalation: true, // Включить эскалацию транспортов
headers: {'Custom-Header': 'value'}, // HTTP заголовки
query: {'token': 'abc123'}, // Query параметры
enableLogging: false, // Включить логи
);
final socket = SocketIOClient(options);
Состояния подключения
enum SocketIOConnectionState {
disconnected, // Отключен
connecting, // Подключается
connected, // Подключен
reconnecting, // Переподключается
error, // Ошибка
}
Обработка ошибок
socket.on('error', (error) {
if (error is TimeoutException) {
print('Таймаут подключения');
} else if (error is SocketException) {
print('Сетевая ошибка: ${error.message}');
} else {
print('Неизвестная ошибка: $error');
}
});
Примеры использования
Чат приложение
class ChatService {
late SocketIOClient socket;
void connect() {
socket = io('http://localhost:3000');
socket.on('connect', (_) {
print('Подключен к чату');
});
socket.on('new_message', (data) {
final message = Message.fromJson(data);
_handleNewMessage(message);
});
socket.on('user_joined', (data) {
print('${data['username']} присоединился');
});
}
void sendMessage(String text) {
socket.emit('send_message', {
'text': text,
'timestamp': DateTime.now().toIso8601String(),
});
}
void dispose() {
socket.dispose();
}
}
Real-time уведомления
class NotificationService {
late SocketIOClient socket;
void initialize(String userId) {
socket = io('http://localhost:3000',
query: {'userId': userId},
);
socket.on('notification', (data) {
_showNotification(data['title'], data['body']);
});
socket.on('badge_update', (data) {
_updateBadgeCount(data['count']);
});
}
}
Тестирование
Запуск тестов:
flutter test
Совместимость
- Flutter: >=1.17.0
- Dart: ^3.10.3
- Socket.IO Server: v4.x
Лицензия
MIT License
Поддержка
Если у вас есть вопросы или предложения, создайте issue в репозитории.