Flutter通信插件hotline的使用

发布于 1周前 作者 bupafengyu 来自 Flutter

Flutter通信插件hotline的使用

创建到ActionCable服务器的连接,并使用类似ActionCable的订阅API。

Dart 示例

void main() {
  // 创建一个到ActionCable服务器的连接
  final hotline = Hotline('ws://localhost:3000/cable');

  // 接下来,订阅一个频道
  // ActionCable.server.broadcast("Chat Room", {hello: "Chat room!"})
  // `simpleChannel` onReceived回调将在订阅简单频道名称时被调用
  final subscription = hotline.subscriptions.create('Example Channel');

  // 如果你想广播到资源特定的频道,例如:
  // ChatRoomChannel.broadcast_to(ChatRoom.find(1), {hello: "Chat Room 1"})
  // 那么使用参数化构造函数并传递参数到你的`stream_for`方法
  final subscription = hotline.subscriptions.create({'channel': 'Chat Room', 'id': 1});

  // 或者甚至是Turbo Stream
  final subscription = hotline.subscriptions.create({
    'channel': 'Turbo::StreamsChannel',
    'signed_stream_name': 'IloybGtPaTh2WVhCd0wwSmhjMnRsZEM4eCI=--635611ff87dda934376806f3dbfcdb6b724fa0cbcca9b32684c537ad8eb9390f'
  });

  // 最后,你可以监听连接和频道本身的各种变化...
  hotline.status.listen((state) => print('Hotline Connection State: $state'));
  subscription.status.listen((state) => print('Subscription State: $state'));
  subscription.stream.listen((data) => print('Received On Stream: $data'));
}

Dart 示例:使用回调而不是流

void main() {
  // 使用必要的回调创建一个连接
  final onConnect = (Hotline connection) => print('Hotline Connection State: Connected');
  final onDisconnect = () => print('Hotline Connection State: Disconnected');
  Hotline hotline = Hotline('ws://localhost:3000/cable',
      onConnect: onConnect,
      onDisconnect: onDisconnect
  );

  // 创建一个到ActionCable频道的订阅
  final confirmed = (HotlineSubscription subscription) => print('Subscription State: Confirmed');
  final received  = (Map data) => print('Received On Stream: $data');
  final rejected  = () => print('Subscription State: Rejected');

  // ActionCable.server.broadcast("Chat Room", {hello: "Chat room!"})
  // `simpleChannel` onReceived回调将在订阅简单频道名称时被调用
  HotlineSubscription simpleChannel = hotline.subscriptions.create(
      'Chat Room',
      onConfirmed: confirmed,
      onReceived: received,
      onRejected: rejected
  );

  // 如果你想广播到资源特定的频道,例如:
  // ChatRoomChannel.broadcast_to(ChatRoom.find(1), {hello: "Chat Room 1"})
  // 那么使用参数化构造函数并传递参数到你的`stream_for`方法
  HotlineSubscription resourceChannel = hotline.subscriptions.create(
      {'channel': 'Chat Room', 'id': 1},
      onConfirmed: confirmed,
      onReceived: received,
      onRejected: rejected
  );
}

Flutter

建议使用基于流的接口,并使用StreamBuilder小部件。

连接视图

// 创建包含连接的容器小部件
class HotlineConnectionView extends StatefulWidget {
  final hotline = Hotline('ws://localhost:3000/cable');

  HotlineConnectionView({Key? key}) : super(key: key);

  [@override](/user/override)
  State<HotlineConnectionView> createState() => _HotlineConnectionViewState();
}

class _HotlineConnectionViewState extends State<HotlineConnectionView> {
  [@override](/user/override)
  void initState() {
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream: this.widget.hotline.status,
      builder: (BuildContext context, AsyncSnapshot<HotlineSocketConnectionType> snapshot) {
        if(snapshot.data == HotlineSocketConnectionType.connecting) {
          // 当我们正在等待HotlineSocketConnectionType.connected时,显示一个加载指示器
          return CircularProgressIndicator();
        } else if (snapshot.data == HotlineSocketConnectionType.connected) {
          // 如果我们在这里,我们可以渲染HotlineSubscriptionView以订阅我们想要的频道
          return HotlineSubscriptionView({'channel': 'Chat Room', 'id': 1}, this.widget.hotline);
        } else {
          return Text('未连接');
        }
      }
    );
  }
}

订阅视图

// 用于创建给定频道的HotlineSubscription的小部件
class HotlineSubscriptionView extends StatefulWidget {
  late final HotlineSubscription subscription;
  HotlineSubscriptionView(Map<String, String> channel, Hotline connection) : subscription = connection.subscriptions.create(channel);

  [@override](/user/override)
  _HotlineSubscriptionViewState createState() => _HotlineSubscriptionViewState();
}

class _HotlineSubscriptionViewState extends State<HotlineSubscriptionView> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        children: [
          // 显示当前频道连接状态的StreamBuilder
          StreamBuilder(
            stream: this.widget.subscription.status,
            builder: (BuildContext context, AsyncSnapshot<HotlineSubscriptionRequestState> snapshot) {
              return Text('Subscription Status: ${snapshot.data}');
            },
          ),
          // 另一个StreamBuilder,这次是为了渲染接收到的数据
          StreamBuilder(
            stream: this.widget.subscription.stream,
            builder: (BuildContext context, AsyncSnapshot<Map> snapshot) {
              return Text('Data: ${snapshot.data}');
            },
          ),
        ],
      )
    );
  }
}

更多关于Flutter通信插件hotline的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter通信插件hotline的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,我可以为你提供一个关于如何在Flutter中使用hotline插件进行通信的代码案例。hotline是一个用于Flutter平台间通信的插件,允许你在原生代码(iOS/Android)和Flutter代码之间进行高效的数据传递。

以下是一个简单的例子,展示了如何使用hotline插件在Flutter和原生代码之间进行通信。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加hotline依赖:

dependencies:
  flutter:
    sdk: flutter
  hotline: ^最新版本号 # 请替换为实际的最新版本号

然后运行flutter pub get来安装依赖。

2. 设置原生代码

iOS

ios/Runner/Info.plist中添加必要的权限(如果需要的话)。然后,在ios/Runner/AppDelegate.swift中配置hotline

import UIKit
import Flutter
import hotline

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
    
    // 初始化Hotline
    Hotline.shared.setup()
    
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

Android

android/app/src/main/AndroidManifest.xml中添加必要的权限(如果需要的话)。然后,在android/app/src/main/kotlin/你的包名/MainActivity.kt中配置hotline

package 你的包名

import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
import hotline.HotlinePlugin // 确保导入正确的包路径

class MainActivity: FlutterActivity() {
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        GeneratedPluginRegistrant.registerWith(flutterEngine)
        
        // 初始化Hotline
        HotlinePlugin.registerWith(flutterEngine.dartExecutor.binaryMessenger)
    }
}

3. Flutter代码

在你的Flutter项目中,你可以使用hotline插件来发送和接收消息。以下是一个简单的例子:

import 'package:flutter/material.dart';
import 'package:hotline/hotline.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _messageFromNative = '';

  @override
  void initState() {
    super.initState();
    
    // 监听来自原生代码的消息
    Hotline.eventStream.listen((event) {
      setState(() {
        _messageFromNative = event['message'] ?? '';
      });
    });
    
    // 发送消息到原生代码
    _sendMessageToNative('Hello from Flutter!');
  }

  Future<void> _sendMessageToNative(String message) async {
    try {
      await Hotline.sendMessage({'message': message});
    } catch (e) {
      print('Failed to send message: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Hotline Demo'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'Message from Native: $_messageFromNative',
                style: TextStyle(fontSize: 20),
              ),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: () => _sendMessageToNative('Another message from Flutter!'),
                child: Text('Send Message to Native'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

4. 原生代码接收和发送消息

iOS (Swift)

AppDelegate.swift或任何适当的地方添加以下代码来处理来自Flutter的消息和发送消息回Flutter:

import UIKit
import Flutter
import hotline

// ... (其他代码保持不变)

extension AppDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // ... (其他代码保持不变)
        
        // 监听来自Flutter的消息
        Hotline.shared.listen { event in
            if let message = event["message"] as? String {
                print("Received message from Flutter: \(message)")
                
                // 发送消息回Flutter
                Hotline.shared.send(["message": "Hello from iOS!"])
            }
        }
        
        return true
    }
}

Android (Kotlin)

MainActivity.kt或任何适当的地方添加以下代码来处理来自Flutter的消息和发送消息回Flutter:

package 你的包名

import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
import io.flutter.plugin.common.MethodChannel
import hotline.HotlinePlugin // 确保导入正确的包路径

class MainActivity: FlutterActivity() {
    private val CHANNEL = "your.channel.name" // 替换为你的通道名

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        GeneratedPluginRegistrant.registerWith(flutterEngine)
        
        // 初始化Hotline(已在前面完成,这里仅作为示例)
        HotlinePlugin.registerWith(flutterEngine.dartExecutor.binaryMessenger)
        
        // 设置MethodChannel来监听来自Flutter的消息
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "sendMessage") {
                val message = call.argument<String>("message")
                message?.let {
                    print("Received message from Flutter: $it")
                    
                    // 发送消息回Flutter
                    HotlinePlugin.getInstance(flutterEngine.dartExecutor.binaryMessenger)
                        ?.sendMessage(mapOf("message" to "Hello from Android!"))
                    result.success(null)
                } ?: result.error("INVALID_ARGUMENT", "Message is missing", null)
            } else {
                result.notImplemented()
            }
        }
    }
}

注意:在Android部分,HotlinePlugin可能没有提供直接的sendMessage方法,这里仅作为示例展示了如何使用MethodChannel。实际上,你可能需要根据hotline插件的具体实现来调整代码。

以上代码展示了如何在Flutter和原生代码之间使用hotline插件进行通信。请根据你的具体需求调整代码。

回到顶部