AvoidDirectWebSocket class

禁止业务代码直接使用 WebSocket 底层 API:

  • package:web_socket_channel/...WebSocketChannel / IOWebSocketChannel / HtmlWebSocketChannel 等类直接 new 或调静态 connect
  • dart:ioWebSocket.connect(...)
  • dart:htmlWebSocket(...)(Web 平台)。

禁止:使用 flutter_spine 暴露的 WsClient / DefaultWsClient / WsClientConfig / WsTopicRouter / BaseWsGateway / WsModuleRegistry / WsModuleConfig 等已封装类型。

为什么

  • 业务代码绕过 WsClient 抽象 → 拿不到统一的状态机(WsConnectionState);
  • 没有内置心跳 / 指数退避重连 / topic 订阅 / token 自动刷新;
  • 重连失败后无法接入 EffectShowError / Riverpod observers;
  • 测试时无法注入 _FakeWsChannel,必须真连后端。

改写指引

// ❌ 业务代码
final ch = WebSocketChannel.connect(Uri.parse('wss://api/feed'));
ch.stream.listen(_onMsg);

// ✅ 三层架构(推荐)
// 1. 定义模块配置
final marketWsModule = WsModuleConfig(
  uri: Uri.parse('wss://market-api.example/feed'),
  topicRouter: WsTopicRouter.simple(channelKey: 'channel'),
);

// 2. 注册到 WsModuleRegistry
//    main.dart → FlutterSpineConfig.extraOverrides
WsModuleRegistry.build(modules: [marketWsModule], defaultConfig: ...)

// 3. 创建 Gateway
class MarketWsGateway extends BaseWsGateway {
  MarketWsGateway(super.ws);
  Stream<PriceUpdate> subscribePrice(String chain, String addr) =>
      ws.subscribe('price-info|$chain|$addr', decoder: PriceUpdate.fromRaw);
}

// 4. 页面使用(StreamProvider.autoDispose 自动管理订阅生命周期)
final priceAsync = ref.watch(priceStreamProvider(('eip155:1', 'native')));

豁免

  • flutter_spine 自身的 WebSocket 实现:package/flutter_spine/lib/src/network/**
  • 应用启动 /lib/main.dart / lib/bootstrap.dart
  • 测试 / fixture / example 路径

Constructors

AvoidDirectWebSocket()
const

Properties

code → LintCode
The LintCode that this LintRule may emit.
finalinherited
enabledByDefault bool
Whether the lint rule is on or off by default in an empty analysis_options.yaml
no setterinherited
filesToAnalyze List<String>
A list of glob patterns matching the files that run cares about.
no setterinherited
hashCode int
The hash code for this object.
no setterinherited
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

getFixes() List<Fix>
Obtains the list of Fix associated with this LintRule.
inherited
isEnabled(CustomLintConfigs configs) bool
Checks whether this lint rule is enabled in a configuration file.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
run(CustomLintResolver resolver, ErrorReporter reporter, CustomLintContext context) → void
Emits lints for a given file.
startUp(CustomLintResolver resolver, CustomLintContext context) Future<void>
Emits lints for a given file.
inherited
testAnalyzeAndRun(File file) Future<List<AnalysisError>>
Analyze a Dart file and runs this assist in test mode.
inherited
testRun(ResolvedUnitResult result, {Pubspec? pubspec}) Future<List<AnalysisError>>
Runs this assist in test mode.
inherited
toString() String
A string representation of this object.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited