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

1 回复

更多关于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'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
回到顶部