Flutter+WebRTC+gRPC开发点对点加密即时通讯APP--gRPC点对点通信

Flutter+WebRTC+gRPC开发点对点加密即时通讯APP--gRPC点对点通信

开篇

基于Flutter+WebRTC+gRPC,开发一款点对点加密、跨端、即时通讯APP,实现文字、音视频通话聊天,同时支持图片、短视频等文件传输功能,计划支持Windows、Android平台。我准备将自己的学习和实践过程记录下来,同时分享给大家,欢迎大家一起研讨交流。这个工程是利用自己的业余时间来实现的,不定时更新。本篇文章基于gRPC协议实现点对点通讯。

gRPC简介

RPC,全称Remote Procedure Call,中文译为远程过程调用。通俗地讲,使用RPC进行通信,调用远程函数就像调用本地函数一样,RPC底层会做好数据的序列化与传输,从而能使我们更轻松地创建分布式应用和服务。gRPC 是一种现代开源高性能远程过程调用 (RPC) 可以在任何环境中运行的框架。它可以有效地连接服务 在数据中心内和跨数据中心,支持对负载均衡、跟踪、 运行状况检查和身份验证。它也适用于最后一英里 分布式计算,将设备、移动应用程序和浏览器连接到 后端服务。gRPC是免费且开源的,由谷歌出品。

实现一个gRPC服务端和客户端,主要包含下边4步:

1.安装 protobuf 依赖

2.编写 proto 文件

3.编译 proto 文件

4.编写server端和编写client端

Dart语言下gRPC快速入门

Dart语言下使用gRPC前提条件包括,Dart 2.12 或更高版本 ,protoc版本 3,Dart 插件。

插件安装

Dart语言下安装protoc-gen-dart插件

shell 复制代码
dart pub global activate protoc_plugin

安装完成后,记得将插件路径添加到系统路径。

插件路径:

shell 复制代码
C:\Users\****\AppData\Local\Pub\Cache\bin

protoc安装与编辑

我们还需要安装protoc,并将路径添加到系统路径,protoc可以直接从Github下载。

接着,我们需要编辑我们的.proto文件,.proto文件中为要序列化的每个数据结构添加消息,并指定名称和类型:

proto 复制代码
syntax = "proto3";

package routeguide;

service RouteGuide {
  rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
}

message RouteNote {
  string message = 1;
}

syntax = "proto3" 说明proto为3版本。我们定义一个RouteGuide服务,其中包含RouteChat方法,我们使用双向流式RPC,就是说可以全双工通信,实现方式很简单,只需要在RouteChat的输入输出RouteNote前都加上stream即可。RouteNote就是我们的定义的请求和返回了。

编写完.proto文件后,使用下边的命令编译protobuf文件。

shell 复制代码
protoc lib/protos/guide.proto --dart_out=grpc:.

--dart_out=grpc:.指定输出路径,lib/protos/guide.proto指定.proto文件位置。执行完命令后,我们就可以看到自动生成的Dart代码文件了,这些自动生成的文件,我们不要手动编辑哦。

dart 复制代码
guide.pb.dart
guide.pbenum.dart
guide.pbgrpc.dart
guide.pbjson.dart

服务器端实现

现在我们首先搭建一个gRPC服务器,先引入头文件,然后实现一个servermain函数,在servermain函数中,我们使用grpc.Server.create创建一个server,然后设置监听IP地址和端口,在server中指定调用服务类为RouteGuideService。

dart 复制代码
import 'package:grpc/grpc.dart' as grpc;
import 'protos/guide.pbgrpc.dart';

servermain() async {
  debugPrint('Server start...');
  final server = grpc.Server.create(services: [RouteGuideService()]);
  await server.serve(
    address: '192.168.31.9',
    port: 8888,
  );
  debugPrint('Server listening on port ${server.port}...');
}

在RouteGuideService中实现routeChat方法,远端有访问过来时,就将请求打印出来,同时,将"server message"返回给客户端,实现双向通信。实际上也就是在客户端调用服务端的routeChat函数。

dart 复制代码
class RouteGuideService extends RouteGuideServiceBase {
  @override
  Stream<RouteNote> routeChat(
      grpc.ServiceCall call, Stream<RouteNote> request) async* {
    await for (var note in request) {
      debugPrint("get client message: ");
      debugPrint(note.message);
      yield RouteNote(message: "server message");
    }
  }
}

客户端实现

现在来实现客户端,引入guide.pbgrpc.dart和grpc/grpc.dart文件,定义全局变量stub用来调用远程函数,创建主函数clientmain,在ClientChannel中设置访问服务器端口和IP,设置 ChannelCredentials.insecure来禁用加密通信,不适用加密证书,加密通信后期再谈论。接着调用RouteGuideClient连接远端服务器,将返回值赋值给stub。最后调用runRouteChat函数,此函数中实现我们数据交互逻辑。

dart 复制代码
import 'protos/guide.pbgrpc.dart';
import 'package:grpc/grpc.dart';

late RouteGuideClient stub;

clientmain() {
  final channel = ClientChannel('192.168.31.9',
      port: 8888,
      options:
          const ChannelOptions(credentials: ChannelCredentials.insecure()));
  stub = RouteGuideClient(channel,
      options: CallOptions(timeout: const Duration(seconds: 30)));
  runRouteChat();
}

在runRouteChat函数中调用stub.routeChat来进行远端函数调用,传入的outgoingNotes函数来向服务端发出申请,返回值call就是服务端返回的信息了。

dart 复制代码
Future<void> runRouteChat() async {
  final call = stub.routeChat(outgoingNotes());
  await for (var note in call) {
    debugPrint('Got server message:');
    debugPrint(note.message);
  }
}

outgoingNotes函数实现的功能是,简单的向服务端发送五次信息。

dart 复制代码
  Stream<RouteNote> outgoingNotes() async* {
    for (var i = 0; i < 5; i++) {
      debugPrint('Sending message to server');
      yield RouteNote(message: "client message");
    }
  }

gRPC连接建立,通信完成

上述配置和代码都完成后,就可以进行gRPC连接,实现全双工通信了,效果图如下:

相关推荐
火柴就是我15 小时前
flutter 之真手势冲突处理
android·flutter
Speed12315 小时前
`mockito` 的核心“打桩”规则
flutter·dart
法的空间15 小时前
Flutter JsonToDart 支持 JsonSchema
android·flutter·ios
恋猫de小郭16 小时前
Android 将强制应用使用主题图标,你怎么看?
android·前端·flutter
玲珑Felone16 小时前
从flutter源码看其渲染机制
android·flutter
ALLIN2 天前
Flutter 三种方式实现页面切换后保持原页面状态
flutter
Dabei2 天前
Flutter 国际化
flutter
Dabei2 天前
Flutter MQTT 通信文档
flutter
Dabei2 天前
Flutter 中实现 TCP 通信
flutter
孤鸿玉2 天前
ios flutter_echarts 不在当前屏幕 白屏修复
flutter