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。

dart 复制代码
synchronized: ^3.1.0

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

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

dart 复制代码
// 添加连接计数器和锁
int _activeConnections = 0;
String? _currentClientIP; // 记录当前连接的客户端IP
final _connectionLock = Lock();

// 创建连接管理器
class ConnectionManager {
  static String _getClientIP(ServiceCall call) {
    try {
      // 尝试从客户端元数据中获取IP
      if (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');

        // 如果没有活动连接了,清除当前客户端IP
        if (_activeConnections == 0) {
          _currentClientIP = null;
          print('All connections closed, ready for new clients');
        }
      }
    });
  }
}

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

dart 复制代码
// 给XXXService添加连接限制
class ConnectionLimitedXXXService extends XXXServiceBase {

  @override
  Future<StringReply> usrFunCallReq(
      ServiceCall call, StringRequest request) async {
    await ConnectionManager.checkConnection(call); // 增加连接判断处理
    try {
      // procedure
      return StringReply()
        ..message = jsonEncode(xxx);
    } finally {
      await ConnectionManager.releaseConnection(call); // 增加连接清除处理
    }
  }
  ...
}
相关推荐
stark张宇3 天前
微服务架构必备:Gin + gRPC + Consul + Nacos + GORM 打造用户服务
微服务·gin·grpc
雮尘5 天前
手把手带你玩转Android gRPC:一篇搞定原理、配置与客户端开发
android·前端·grpc
LawrenceLan7 天前
30.Flutter 零基础入门(三十):GridView 网格布局 —— 九宫格与商品列表必学
开发语言·前端·flutter·dart
LawrenceLan8 天前
31.Flutter 零基础入门(三十一):Stack 与 Positioned —— 悬浮、角标与覆盖布局
开发语言·前端·flutter·dart
REDcker24 天前
gRPC开发者快速入门
服务器·c++·后端·grpc
REDcker24 天前
gRPC完整文档
服务器·网络·c++·网络协议·grpc
浩辉_1 个月前
Dart - 内存管理与垃圾回收(GC)深度解析
flutter·dart
浩辉_1 个月前
Dart - 认识Sealed
flutter·dart
JMchen1231 个月前
跨平台相机方案深度对比:CameraX vs. Flutter Camera vs. React Native
java·经验分享·数码相机·flutter·react native·kotlin·dart
雨季6661 个月前
Flutter 三端应用实战:OpenHarmony “微光笔记”——在灵感消逝前,为思想点一盏灯
开发语言·javascript·flutter·ui·dart