Flutter实时通信插件pusher_client_socket的使用
Flutter 实时通信插件 pusher_client_socket
的使用
简介
pusher_client_socket
是一个用于通过 WebSocket 连接到 Pusher 服务器的 Dart 库。它提供了一个易于使用的 API 来订阅频道、绑定事件监听器以及向服务器发送事件。
特性
- 使用 WebSocket 连接到 Pusher 服务器。
- 支持所有平台(Android, iOS, MacOS, WindowsOS, LinuxOS, Web)。
- 订阅公共、私有、加密私有和存在频道。
- 绑定事件监听器以处理自定义和 Pusher 特定事件。
- 自动重连逻辑以处理连接中断。
- 活动检查机制以确保连接保持活动状态。
安装
在 pubspec.yaml
文件中添加以下依赖:
dependencies:
pusher_client_socket: ^0.0.2+6
然后运行:
flutter pub get
或者使用 pub add
:
flutter pub add pusher_client_socket
使用示例
1. 导入库
/// 导入 pusher client
import 'package:pusher_client_socket/pusher_client_socket.dart';
/// 导入频道
import 'package:pusher_client_socket/channels/channel.dart';
import 'package:pusher_client_socket/channels/private_channel.dart';
import 'package:pusher_client_socket/channels/private_encrypted_channel.dart';
import 'package:pusher_client_socket/channels/presence_channel.dart';
2. 初始化连接选项
使用默认 Pusher 服务器
final options = PusherOptions(
key: 'PUSHER-KEY',
cluster: 'mt1',
wsPort: 80,
wssPort: 443,
authOptions: PusherAuthOptions(
endpoint: 'http://localhost/broadcasting/auth',
headers: {
'Accept': 'application/json',
'Authorization': 'Bearer AUTH-TOKEN'
}
),
autoConnect: false,
);
指定服务器(例如 Laravel/Reverb)
final options = PusherOptions(
key: 'REVERB_APP_KEY',
host: 'localhost', // REVERB_HOST
wsPort: 6001, // REVERB_PORT
encrypted: false, // (注意:如果你使用 wss 连接,请启用此项)
authOptions: PusherAuthOptions(
endpoint: 'http://localhost/broadcasting/auth',
headers: {
'Accept': 'application/json',
'Authorization': 'Bearer AUTH-TOKEN'
}
),
autoConnect: false,
);
3. 初始化客户端并连接
final pusherClient = PusherClient(options);
pusherClient.onConnectionEstablished((data) {
print("Connection established - socket-id: ${pusherClient.socketId}");
});
pusherClient.onConnectionError((error) {
print("Connection error - $error");
});
pusherClient.onError((error) {
print("Error - $error");
});
pusherClient.onDisconnected((data) {
print("Disconnected - $data");
});
pusherClient.connect();
4. 订阅频道
/// 订阅公共频道
final publicChannel = pusherClient.channel('channel-1');
/// 订阅私有频道
final privateChannel = pusherClient.channel('private-channel-2');
// 或者
final privateChannel = pusherClient.private('channel-2');
/// 订阅加密私有频道
final privateEncryptedChannel = pusherClient.channel('private-encrypted-channel-3');
// 或者
final privateEncryptedChannel = pusherClient.privateEncrypted('channel-3');
/// 订阅存在频道
final presenceChannel = pusherClient.channel("presence-channel-4");
// 或者
final presenceChannel = pusherClient.presence("channel-4");
5. 监听事件
channel.bind('EventName', (data) {
print('event received - EventName - $data');
});
6. 在私有或存在频道上触发事件
privateChannel.trigger('client-EventName', data);
// 或者
privateChannel.trigger('EventName', data);
// 或者
presenceChannel.trigger('client-EventName', data);
// 或者
presenceChannel.trigger('EventName', data);
7. 取消订阅频道
channel.unsubscribe();
完整示例 Demo
以下是一个完整的 Flutter 示例应用,展示了如何使用 pusher_client_socket
插件进行实时通信。
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:pusher_client_socket/pusher_client_socket.dart';
void main() {
runApp(const MyApp());
}
const String TOKEN = "AUTH_TOKEN";
const String KEY = "PUSHER_KEY";
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Pusher Client Socket',
theme: ThemeData(
useMaterial3: true,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late PusherClient client;
final tokenController = TextEditingController(text: TOKEN);
bool connected = false;
bool connecting = false;
String? connectError;
String? socketId;
final channelController = TextEditingController(text: "Chat.1");
PrivateChannel? channel;
bool subscribed = false;
bool subscribing = false;
final messageController = TextEditingController();
String messages = '';
void connect() {
if (tokenController.text.isEmpty) {
return;
}
setState(() {
connecting = true;
});
client = PusherClient(
options: PusherOptions(
host: "localhost",
wsPort: 6001,
encrypted: false,
authOptions: PusherAuthOptions(
"http://localhost/api/broadcasting/auth",
headers: {
"Accept": "application/json",
"Authorization": "Bearer ${tokenController.text}",
},
),
key: KEY,
enableLogging: true,
autoConnect: false,
),
);
client.onConnectionEstablished((data) => setState(() {
connected = true;
socketId = client.socketId;
connecting = false;
client
.subscribe("private-encrypted-User.1")
.bind("UserUpdatedEvent", (data) => print("UserUpdatedEvent - $data"));
}));
client.onDisconnected((reason) => setState(() {
connected = false;
socketId = client.socketId;
connecting = false;
}));
client.onConnectionError((error) => setState(() {
connectError = "$error";
connecting = false;
}));
client.onError((error) => setState(() {
connectError = "$error";
connecting = false;
}));
client.connect();
}
void disconnect() {
setState(() {
connecting = true;
});
client.disconnect();
}
void subscribe() {
setState(() {
subscribed = false;
subscribing = true;
});
channel = client.presence(channelController.text);
channel!.onSubscriptionSuccess((data) => setState(() {
print("Subscribe success $data");
subscribed = true;
subscribing = false;
}));
channel!.bind("client-whisper", (data) {
print("test event - $data");
setState(() {
messages += "client: ${data["message"]}\n";
});
});
channel!.subscribe();
}
void unSubscribe() {
channel!.unsubscribe();
setState(() => subscribed = false);
}
void sendMessage() {
channel!.trigger("whisper", {"message": messageController.text});
setState(() {
messages += "you: ${messageController.text}\n";
});
messageController.clear();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: const Text('Pusher Client Socket'),
),
body: SizedBox.expand(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (connecting)
const CircularProgressIndicator()
else ...[
if (!connected)
TextField(
controller: tokenController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Token',
),
),
ElevatedButton(
onPressed: connected ? disconnect : connect,
child: Text(
connected ? 'Disconnect' : 'Connect',
style: TextStyle(
color: connected ? Colors.red : Colors.green,
),
),
),
if (connectError != null)
Text(
connectError!.substring(0, min(400, connectError!.length)),
style: const TextStyle(
color: Colors.red,
fontSize: 20,
),
),
],
if (connected) ...[
Text(
'Socket-ID: $socketId',
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
const Divider(),
if (!subscribed)
Row(
children: [
const Text(
"Channel: ",
style: TextStyle(fontSize: 18),
),
Flexible(
child: TextField(
controller: channelController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
),
),
),
],
),
if (subscribing)
const CircularProgressIndicator()
else ...[
ElevatedButton(
onPressed: subscribed ? unSubscribe : subscribe,
child: Text(
subscribed ? 'unsubscribe' : 'subscribe',
style: TextStyle(
color: subscribed ? Colors.red : Colors.green,
),
),
),
if (subscribed) ...[
const Divider(),
Row(
children: [
Flexible(
child: TextField(
controller: messageController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
),
),
),
ElevatedButton(
onPressed: sendMessage,
child: const Text('Send'),
),
SizedBox(
height: 200,
child: SingleChildScrollView(
child: Text(messages),
),
),
],
),
],
],
],
],
),
),
),
);
}
}
这个示例展示了如何初始化 Pusher 客户端、连接到服务器、订阅频道、监听事件以及发送消息。你可以根据需要修改和扩展此示例。
更多关于Flutter实时通信插件pusher_client_socket的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter实时通信插件pusher_client_socket的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用pusher_client_socket
插件进行实时通信的代码示例。这个示例将展示如何连接到Pusher服务器,订阅一个频道,并监听事件。
首先,确保你已经在pubspec.yaml
文件中添加了pusher_client_socket
依赖:
dependencies:
flutter:
sdk: flutter
pusher_client_socket: ^x.y.z # 替换为最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,在你的Flutter项目中创建一个新的Dart文件(例如pusher_service.dart
),并编写以下代码:
import 'package:flutter/material.dart';
import 'package:pusher_client_socket/pusher_client_socket.dart';
class PusherService {
late PusherClient _pusherClient;
late Channel _channel;
PusherService({required String key, required String cluster}) {
_pusherClient = PusherClient(
key: key,
cluster: cluster,
enableLogging: true,
);
_pusherClient.connect().then((value) {
print("Connected to Pusher!");
_subscribeToChannel();
}).catchError((error) {
print("Error connecting to Pusher: $error");
});
}
void _subscribeToChannel() {
_channel = _pusherClient.subscribe('my-channel');
_channel.bind('my-event', (data) {
print("Received event: $data");
// 在这里处理接收到的事件数据
});
}
void disconnect() {
_pusherClient.disconnect();
}
}
在上面的代码中,我们创建了一个PusherService
类,它负责处理与Pusher的连接、频道订阅和事件监听。你需要替换key
和cluster
参数为你的Pusher应用密钥和集群信息。
现在,在你的主应用程序文件(例如main.dart
)中,使用这个服务:
import 'package:flutter/material.dart';
import 'pusher_service.dart';
void main() {
// 初始化Pusher服务
final pusherService = PusherService(
key: 'YOUR_PUSHER_KEY', // 替换为你的Pusher应用密钥
cluster: 'YOUR_PUSHER_CLUSTER', // 替换为你的Pusher集群(例如 'ap2' 或 'eu')
);
runApp(MyApp(pusherService: pusherService));
}
class MyApp extends StatelessWidget {
final PusherService pusherService;
MyApp({required this.pusherService});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Pusher Demo'),
),
body: Center(
child: Text('Listening for events...'),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// 断开连接(可选)
pusherService.disconnect();
},
tooltip: 'Disconnect',
child: Icon(Icons.disconnect),
),
),
);
}
}
在这个示例中,我们创建了一个简单的Flutter应用程序,它在启动时初始化PusherService
并连接到Pusher。应用程序会显示一个文本和一个浮动操作按钮,点击按钮将断开与Pusher的连接(虽然在实际应用中,你可能会有更复杂的逻辑来处理连接和断开连接)。
请注意,为了完整性和实际使用,你需要确保你的Pusher应用已经配置好,并且你正在监听的频道和事件是存在的。此外,你可能还需要处理更多的错误情况和连接状态变化。
希望这个示例能帮助你开始在Flutter项目中使用pusher_client_socket
插件进行实时通信!