当前位置: 首页 > ds >正文

dart实现单client连接的grpc server (以ip地址作判断)

资料补充
1、grpc在dart中的插件:https://pub.dev/packages/grpc
2、grpc的示例程序:https://github.com/grpc/grpc-dart/tree/master/example

如标题,假设现在已有grpc client/server程序。我这里的逻辑比较简单,基于ip地址的简单限制访问,但是允许来自一个ip地址的多次访问。
具体的实现逻辑在于,当接收到一个来自 client 的 grpc 接口访问,则优先获取client的ip信息:
如果和之前连接的IP地址相同或者之前还未有已连接的client,则允许连接并访问server;
否则,新的连接请求会收到 “Server is already handling another client” 错误;
当已连接的客户端断开连接时,连接计数会正确减少,允许新的client连接。

step1、导入需要的插件 .dart。

synchronized: ^3.1.0import 'dart:async';
import 'dart:io';
import 'package:grpc/grpc.dart';
import 'package:synchronized/synchronized.dart';

step2、增加一个连接管理的类。

// 添加连接计数器和锁
int _activeConnections = 0;
String? _currentClientIP; // 记录当前连接的客户端IP
final _connectionLock = Lock();// 创建连接管理器
class ConnectionManager {static String _getClientIP(ServiceCall call) {try {// 尝试从客户端元数据中获取IPif (call.clientMetadata != null) {// 检查X-Forwarded-For头(用于代理场景)final forwardedFor = call.clientMetadata!['x-forwarded-for'];if (forwardedFor != null && forwardedFor.isNotEmpty) {return forwardedFor;}// 检查X-Real-IP头(某些代理服务器使用)final realIP = call.clientMetadata!['x-real-ip'];if (realIP != null && realIP.isNotEmpty) {return realIP;}}// 尝试从远程地址获取IP(直接连接场景)if (call.remoteAddress != null) {return call.remoteAddress.toString();}} catch (e) {print('Error getting client IP: $e');}return 'Unknown IP';}static Future<void> checkConnection(ServiceCall call) async {bool canConnect = false;String clientIP = _getClientIP(call);await _connectionLock.synchronized(() {if (_activeConnections == 0) {// 没有活动连接,允许新连接_activeConnections++;_currentClientIP = clientIP;canConnect = true;print('New client connected from IP: $clientIP. Active connections: $_activeConnections');} else if (clientIP == _currentClientIP) {// 相同IP的客户端,允许连接_activeConnections++;canConnect = true;print('Additional connection from same IP: $clientIP. Active connections: $_activeConnections');} else {// 不同IP的客户端,拒绝连接print('Connection rejected for client IP: $clientIP - server is handling client from IP: $_currentClientIP');}});if (!canConnect) {throw GrpcError.unavailable('Server is already handling another client from different IP');}}static Future<void> releaseConnection(ServiceCall call) async {String clientIP = _getClientIP(call);await _connectionLock.synchronized(() {if (_activeConnections > 0) {_activeConnections--;print('Client disconnected from IP: $clientIP. Active connections: $_activeConnections');// 如果没有活动连接了,清除当前客户端IPif (_activeConnections == 0) {_currentClientIP = null;print('All connections closed, ready for new clients');}}});}
}

step3、在client发送grpc请求后,server端在服务类的实际操作函类前后加上连接管理类的判断,以及不符后的连接清除处理。

// 给XXXService添加连接限制
class ConnectionLimitedXXXService extends XXXServiceBase {Future<StringReply> usrFunCallReq(ServiceCall call, StringRequest request) async {await ConnectionManager.checkConnection(call); // 增加连接判断处理try {// procedurereturn StringReply()..message = jsonEncode(xxx);} finally {await ConnectionManager.releaseConnection(call); // 增加连接清除处理}}...
}
http://www.xdnf.cn/news/10101.html

相关文章:

  • Yum配置第三方源与本地源详解
  • 日常--OBS+mediamtx实现本地RTMP推流环境搭建(详细图文)
  • RPG17.蓝图函数库与轻重攻击连击
  • C++ 5.29 dddd
  • 【深度剖析】义齿定制行业数字化转型模式创新研究(上篇2:痛点和难点分析)
  • AI智能监控系统:赋能厂区安全管理的数智化革新
  • [Dify] 如何应对明道云API数据过长带来的Token超限问题
  • OAuth协议中的Token、Ticket
  • (NAT64)IPv6网络用户访问IPv4网络服务器(动态映射方式)
  • Linux服务器时间同步——Chronyd
  • MyBatis动态SQL
  • Baklib知识中台驱动业务创新
  • 【HarmonyOS 5】鸿蒙中的UIAbility详解(二)
  • 深化生态协同,宁盾身份域管完成与拓波软件兼容互认证
  • 19、Python字符串高阶实战:转义字符深度解析、高效拼接与输入处理技巧
  • 2.2.1 05年T4
  • Python 连接 MinIO (一)
  • wsl2 docker重启后没了
  • Cobra CLI 工具使用指南:构建 Go 语言命令行应用的完整教程
  • 激励电平与频差的微妙平衡:晶振选型不可忽视的细节
  • C#和VisionPro联合编程-硬币正反面检测
  • SL3038 宽耐压150V降压12V2.5A、5V2.5A降压恒压电源芯片
  • 用户界面禁忌——基础原则
  • 函数指针和指针函数的核心区别
  • iOS 获取Wifi信息
  • 重温经典算法——冒泡排序
  • 国产分子动力学引擎——GPUMD本地部署教程:专为 NVIDIA GPU 加速设计
  • leetcode:372. 超级次方(python3解法,数学相关算法题)
  • litctf2025复现
  • [mcu]系统频率