Flutter连接管理插件vdotok_connect的使用
Flutter连接管理插件vdotok_connect的使用
获取开始
在使用 vdotok_connect
插件之前,需要确保已经将该插件添加到项目的依赖中。请参考以下步骤进行配置。
iOS
在你的项目根目录下的 ios/Runner/Info.plist
文件中添加以下条目:
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) Camera Usage!</string>
<key>NSMicrophoneUsageDescription</key>
<string>$(PRODUCT_NAME) Microphone Usage!</string>
Android
确保在你的 AndroidManifest.xml
文件中添加了以下权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
创建客户端实例
首先我们需要创建一个 Emitter
客户端实例:
Emitter emitter = Emitter.instance;
添加监听器
以下是主要的回调和监听器:
emitter.onConnect = (bool response) {
// 当你连接到Emitter时调用
};
emitter.onPresence = (String response) {
// 当你获取到用户的在线状态时调用
};
emitter.onSubscribe = (String value) {
// 当用户订阅了一个群组时调用
};
emitter.onMessage = (String mesg) async {
// 当有pub/sub事件发生时调用
};
emitter.internetConnectivityCallBack = (String mesg) {
// 当设备连接或断开互联网时调用
};
模型
以下是使用的模型:
// 用于登录/注册
class User {
final String auth_token;
final String authorization_token;
final String email;
final String full_name;
final String message;
final int process_time;
final String ref_id;
final int status;
final int user_id;
}
// 用于群组
class GroupModel {
dynamic admin_id;
dynamic auto_created;
dynamic channel_key;
dynamic channel_name;
dynamic group_title;
dynamic id;
dynamic created_datetime;
}
// 用于获取所有用户
class Contact {
int user_id;
dynamic email;
String ref_id;
String full_name;
}
// 用于聊天
class ChatModel {
var id;
var to;
var key;
var from;
var type;
var content;
var date;
int status;
var size;
var isGroupMessage;
var subtype;
}
常量
以下是使用的常量类:
// 用于通知消息状态
class ReceiptType {
static var sent = 1;
static var delivered = 2;
static var seen = 3;
}
// 用于文件类型识别
class MediaType {
static int image = 0;
static int audio = 1;
static int video = 2;
static int file = 3;
}
// 用于通知类型识别
class NotificationType {
static const String newGroup = "new";
static const String deleteGroup = "delete";
static const String modifyGroup = "modify";
}
// 用于消息类型识别
class MessageType {
static const String text = "text";
static const String media = "media";
static const String file = "file";
static const String thumbnail = "thumbnail";
static const String path = "path";
static const String typing = "typing";
static const String ftp = "ftp";
static const String acknowledge = "acknowledge";
static const String receipts = "receipts";
}
SDK 方法
连接 Socket
使用此方法连接 Socket:
emitter.connect(
String clientId, // 在登录/注册响应中
bool reconnectivity, // true
String refId, // 在登录/注册响应中
String authorizationToken, // 在登录/注册响应中
String projectId,
String host, // 在登录/注册响应中
String port // 在登录/注册响应中
);
订阅
使用此方法订阅聊天或群组:
emitter.subscribe(String channelKey, String channelName);
订阅 Presence
使用此方法来确认用户的存在:
emitter.subscribePresence(String channelKey, String channelName, bool changes, bool status);
发布
使用此方法发布消息,对象类型可以是文本、音频、视频、文档或图像类型:
var sendMessage = {
"from": // 你的refId
"content": // 文本/文件/图像/视频,mp3
"id": // 随机ID
"key": // 群组通道键
"subType": // 在媒体共享时使用文件、图像、视频、音频,即MediaType.image
"fileExtension": // 在媒体共享时使用,即.mp3, .doc, .mp4
"type": // MessageType枚举值,即MessageType.text
"to": // 通道名称
"isGroupMessage": false,
"date": // 当前日期
"status": // ReceiptType枚举值,即ReceiptType.sent
"size": 0.0
};
emitter.publish(String channelKey, String channelName, Map<String, dynamic> sendMessage, int ttl);
发布通知
使用此方法发布群组创建、删除和修改的通知:
var tempdata = {
"from": // 你的refId
"data": {
"action": "new", // new, modify, delete
"groupModel": // 使用上面提到的GroupModel
},
"to": // 群组参与者refId列表
};
emitter.publishNotification(Map<String, dynamic> tempdata);
监听互联网连接/断开连接
使用此方法监听每次设备连接或断开互联网时的变化:
emitter.checkConnectivity();
检查互联网状态
使用此方法检查设备是否连接到互联网,它将返回布尔值:
emitter.getInternetStatus();
示例
以下是一个完整的示例代码:
import 'dart:convert';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:vdotok_connect/vdotok_connect.dart';
Emitter emitter = Emitter.instance;
bool isSocketConnect = false;
class MyApp extends StatefulWidget {
const MyApp({Key key}) : super(key: key);
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
[@override](/user/override)
void initState() {
super.initState();
emitter.connect(
clientId: getUser!.user_id.toString(),
reconnectivity: true,
refId: getUser!.ref_id,
authorizationToken: getUser!.authorization_token,
projectId: project_id,
host: authProvider.host,
port: authProvider.port
);
emitter.onConnect = (bool response) {
if (response) {
setState(() {
isSocketConnect = true;
});
} else {
setState(() {
isSocketConnect = false;
});
}
};
emitter.onSubscribe = (String value) {
if (value == groups!.last!.channel_key + "/" + groups!.last!.channel_name) {
changeState();
}
};
emitter.onPresence = (String response) {
handlePresence(json.decode(response));
};
emitter.onMessage = (String msg) async {
var message = json.decode(msg); // 用于未来的变量
};
}
void subscribeChannel(String channelKey, String channelName) {
emitter.subscribe(channelKey, channelName);
}
void subscribePresence(String channelKey, String channelName, bool changes, bool status) {
emitter.subscribePresence(channelKey, channelName, changes, status);
}
void sendMessage() {
var tempData = {
"id": generateMd5(groupModel.channel_key),
"to": groupModel.channel_name,
"key": groupModel.channel_key,
"from": getUser!.ref_id,
"type": MessageType.ftp || MediaType.text,
"content": textController.text,
"size": 0.0,
"isGroupMessage": false,
"date": ((DateTime.now()).millisecondsSinceEpoch).round(),
"status": ReceiptType.sent,
"subType": MediaType.image,
"fileExtension": ".jpg"
};
emitter.publish(groupModel.channel_key, groupModel.channel_name, tempData, 0);
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('vdotok_connect Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(isSocketConnect ? '已连接' : '未连接'),
ElevatedButton(
onPressed: () {
subscribeChannel(groupModel.channel_key, groupModel.channel_name);
},
child: Text('订阅频道'),
),
ElevatedButton(
onPressed: () {
subscribePresence(groupModel.channel_key, groupModel.channel_name, true, true);
},
child: Text('订阅存在'),
),
ElevatedButton(
onPressed: () {
sendMessage();
},
child: Text('发送消息'),
),
],
),
),
);
}
}
更多关于Flutter连接管理插件vdotok_connect的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter连接管理插件vdotok_connect的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
vdotok_connect
是 VdoTok 提供的一个 Flutter 插件,用于在 Flutter 应用程序中实现实时音视频通信功能。它可以帮助开发者轻松集成音视频通话功能到他们的应用中。
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 vdotok_connect
插件的依赖:
dependencies:
flutter:
sdk: flutter
vdotok_connect: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get
来获取依赖。
2. 初始化插件
在你的 Dart 代码中,首先需要导入 vdotok_connect
插件,并进行初始化。
import 'package:vdotok_connect/vdotok_connect.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('VdoTok Connect Example'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
// 初始化 VdoTok Connect
VdotokConnect.initialize(
apiUrl: "https://api.vdotok.com/API/v0/",
projectId: "your_project_id",
);
},
child: Text('Initialize VdoTok Connect'),
),
),
),
);
}
}
3. 登录和获取会话
在初始化之后,你需要登录并获取会话。通常,你需要使用用户的身份信息来获取一个会话令牌。
void loginAndGetSession() async {
try {
final response = await VdotokConnect.login(
email: "user@example.com",
password: "password",
);
if (response.success) {
print("Login successful: ${response.data}");
} else {
print("Login failed: ${response.error}");
}
} catch (e) {
print("Error: $e");
}
}
4. 发起音视频通话
一旦你获取到了会话令牌,你可以使用它来发起音视频通话。
void startCall() async {
try {
final response = await VdotokConnect.startCall(
sessionId: "your_session_id",
to: "recipient_user_id",
);
if (response.success) {
print("Call started successfully: ${response.data}");
} else {
print("Call failed to start: ${response.error}");
}
} catch (e) {
print("Error: $e");
}
}
5. 接听和挂断通话
你还可以接听和挂断通话。
void answerCall() async {
try {
final response = await VdotokConnect.answerCall(
callId: "call_id",
);
if (response.success) {
print("Call answered successfully: ${response.data}");
} else {
print("Failed to answer call: ${response.error}");
}
} catch (e) {
print("Error: $e");
}
}
void endCall() async {
try {
final response = await VdotokConnect.endCall(
callId: "call_id",
);
if (response.success) {
print("Call ended successfully: ${response.data}");
} else {
print("Failed to end call: ${response.error}");
}
} catch (e) {
print("Error: $e");
}
}
6. 处理回调
你可能需要处理一些回调,比如通话状态的变化、错误处理等。
VdotokConnect.onCallStatusChanged.listen((status) {
print("Call status changed: $status");
});
VdotokConnect.onError.listen((error) {
print("Error occurred: $error");
});
7. 释放资源
在应用退出或不再需要音视频功能时,记得释放资源。
void dispose() {
VdotokConnect.dispose();
}
8. 完整示例
以下是一个完整的示例,展示了如何初始化、登录、发起通话、接听通话和挂断通话。
import 'package:flutter/material.dart';
import 'package:vdotok_connect/vdotok_connect.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('VdoTok Connect Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
VdotokConnect.initialize(
apiUrl: "https://api.vdotok.com/API/v0/",
projectId: "your_project_id",
);
},
child: Text('Initialize VdoTok Connect'),
),
ElevatedButton(
onPressed: () async {
try {
final response = await VdotokConnect.login(
email: "user@example.com",
password: "password",
);
if (response.success) {
print("Login successful: ${response.data}");
} else {
print("Login failed: ${response.error}");
}
} catch (e) {
print("Error: $e");
}
},
child: Text('Login'),
),
ElevatedButton(
onPressed: () async {
try {
final response = await VdotokConnect.startCall(
sessionId: "your_session_id",
to: "recipient_user_id",
);
if (response.success) {
print("Call started successfully: ${response.data}");
} else {
print("Call failed to start: ${response.error}");
}
} catch (e) {
print("Error: $e");
}
},
child: Text('Start Call'),
),
ElevatedButton(
onPressed: () async {
try {
final response = await VdotokConnect.answerCall(
callId: "call_id",
);
if (response.success) {
print("Call answered successfully: ${response.data}");
} else {
print("Failed to answer call: ${response.error}");
}
} catch (e) {
print("Error: $e");
}
},
child: Text('Answer Call'),
),
ElevatedButton(
onPressed: () async {
try {
final response = await VdotokConnect.endCall(
callId: "call_id",
);
if (response.success) {
print("Call ended successfully: ${response.data}");
} else {
print("Failed to end call: ${response.error}");
}
} catch (e) {
print("Error: $e");
}
},
child: Text('End Call'),
),
],
),
),
),
);
}
}