Flutter实时通信插件signalr_socket的使用

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

Flutter实时通信插件signalr_socket的使用

pub package

A flutter plugin for aspx.net SignalR client for Android, iOS, macOS and Web

开始使用

注意:此库不兼容ASP.NET Core SignalR。

平台支持

Android iOS macOS Web Windows Linux
✔️ ✔️ ✔️ ✔️

添加依赖

pubspec.yaml 文件中添加以下依赖:

dependencies:
  signalr_socket: ^1.1.6 #最新版本

初始化 SignalR Socket 并连接到服务器

SignalrSocket signalrSocket = SignalrSocket(
  url: 'https://signalr.socket.com',
  hubName: 'hubName',
  eventName: 'eventName',
  queryString: {'key': 'value'},
  updateConnectionStatus: (status) {
    debugPrint("signalr socket update connection status ${status.name}");
  },
  newMessage: (message) {
    debugPrint("signalr socket new message $message");
  },
);

signalrSocket.connect();

Android 设置

  1. 在发布模式下为 Android 添加 ProGuard 规则。
  2. 在 Android 项目中创建一个新文件 android/app/proguard-rules.pro
  3. proguard-rules.pro 添加以下行:
-keep class com.github.signalr4j.client.hubs.HubResult { *; }
-keep class com.github.signalr4j.client.hubs.HubInvocation { *; }
-keep class com.github.signalr4j.client.hubs.HubProxy$* { *; }
-keep class com.github.signalr4j.client.hubs.HubConnection {*;}

如果需要使用 HTTP URL,则还需要在 Android 项目的 AndroidManifest.xml 中添加以下行:

<application
        android:usesCleartextTraffic="true">
</application>

Web 设置

  1. 将一些 JS 文件添加到 Web 项目中的 web/signalR_js 文件夹。
  2. 这里 下载 JavaScript 文件。
  3. web/signalR_js 文件夹中添加以下三个文件:jquery.min.js, jquery.signalR-2.4.3.min.jssocketConnection.js
  4. 打开 web/index.html 并在头部添加以下行:
<head>
    <!--其他行-->

    <script defer type="application/javascript" src="signalR_js/jquery.min.js"></script>
    <script defer type="application/javascript" src="signalR_js/jquery.signalR-2.4.3.min.js"></script>
    <script defer type="application/javascript" src="signalR_js/socketConnection.js"></script>
</head>

完整示例 Demo

以下是完整的示例代码,展示了如何使用 signalr_socket 插件进行实时通信:

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

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

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  SignalrSocketConnectionStatus connectionStatus = SignalrSocketConnectionStatus.disconnected;

  late SignalrSocket signalrSocket;

  List<String> outputs = [];

  ScrollController outputScrollController = ScrollController();

  [@override](/user/override)
  void initState() {
    signalrSocket = SignalrSocket(
      url: "http://localhost:8080/signalr",
      hubName: "SignalrSocketHub",
      eventName: "SignalrSocketEvent",
      queryString: {'key': 'value'},
      updateConnectionStatus: (connectionStatus) {
        debugPrint("signalr socket update connection status ${connectionStatus.name}");

        setState(() {
          this.connectionStatus = connectionStatus;
        });
      },
      newMessage: newMessage,
    );

    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('SignalR Socket Example'),
        ),
        body: Column(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Center(
              child: Padding(
                padding: const EdgeInsets.all(16.0),
                child: Text(connectionStatus.name, style: const TextStyle(fontWeight: FontWeight.bold)),
              ),
            ),
            Center(
              child: ElevatedButton(
                onPressed: () {
                  signalrSocket.connect();
                },
                style: ElevatedButton.styleFrom(backgroundColor: Colors.green, foregroundColor: Colors.white),
                child: const Text("Connect"),
              ),
            ),
            const SizedBox(height: 16),
            Center(
              child: ElevatedButton(
                onPressed: () {
                  signalrSocket.disconnect();
                },
                style: ElevatedButton.styleFrom(backgroundColor: Colors.red, foregroundColor: Colors.white),
                child: const Text("Disconnect"),
              ),
            ),
            const Padding(
              padding: EdgeInsets.only(left: 16, top: 16),
              child: Text("Output:"),
            ),
            Expanded(
              child: Scrollbar(
                controller: outputScrollController,
                thumbVisibility: true,
                child: ListView.builder(
                  controller: outputScrollController,
                  itemCount: outputs.length,
                  itemBuilder: (context, index) {
                    final output = outputs[index];

                    return Padding(
                      padding: const EdgeInsets.only(left: 8, right: 8),
                      child: Card(
                        child: Padding(
                          padding: const EdgeInsets.all(8.0),
                          child: Text(output),
                        ),
                      ),
                    );
                  },
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.only(left: 16, right: 16),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  IconButton(
                    onPressed: () {
                      outputScrollController.animateTo(
                        outputScrollController.position.minScrollExtent,
                        duration: const Duration(milliseconds: 100),
                        curve: Curves.easeOut,
                      );
                    },
                    icon: const Icon(Icons.arrow_circle_up),
                  ),
                  IconButton(
                    onPressed: () {
                      setState(() {
                        outputs = [];
                      });
                    },
                    icon: const Icon(Icons.clear_all),
                  ),
                  IconButton(
                    onPressed: () {
                      outputScrollController.animateTo(
                        outputScrollController.position.maxScrollExtent,
                        duration: const Duration(milliseconds: 100),
                        curve: Curves.easeOut,
                      );
                    },
                    icon: const Icon(Icons.arrow_circle_down),
                  )
                ],
              ),
            )
          ],
        ),
      ),
    );
  }

  newMessage(dynamic message) {
    setState(() {
      outputs.add(message.toString());
    });
  }
}

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

1 回复

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


当然,下面是一个关于如何在Flutter应用中使用signalr_socket插件进行实时通信的代码示例。这个插件允许你与ASP.NET Core SignalR服务器进行通信。

首先,确保你的Flutter项目中已经添加了signalr_socket依赖。在你的pubspec.yaml文件中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  signalr_socket: ^x.y.z  # 请替换为最新版本号

然后运行flutter pub get来获取依赖。

接下来,是一个简单的Flutter应用示例,它展示了如何使用signalr_socket连接到SignalR服务器,并处理接收到的消息。

1. 创建SignalR客户端

在你的Flutter项目的lib目录下创建一个新的Dart文件,例如signalr_client.dart,并添加以下代码:

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

class SignalRClient {
  SignalRSocket? _signalR;

  SignalRClient({required String url}) {
    connectToSignalR(url);
  }

  void connectToSignalR(String url) {
    _signalR = SignalRSocket.builder()
        .setUrl(url)
        .withReconnect()
        .withAutomaticReconnect()
        .build();

    _signalR!.onConnect((dynamic data) {
      print("Connected to SignalR server");
    });

    _signalR!.onReceive((dynamic message) {
      print("Received message: $message");
      // 在这里处理接收到的消息,例如更新UI
    });

    _signalR!.onError((dynamic error) {
      print("SignalR error: $error");
    });

    _signalR!.onClose((dynamic data) {
      print("Connection closed");
    });

    _signalR!.connect();
  }

  void sendMessage(String message) {
    if (_signalR!.isConnected()) {
      _signalR!.send("SendMessage", {"message": message});
    } else {
      print("Not connected to SignalR server");
    }
  }

  void disconnect() {
    if (_signalR!.isConnected()) {
      _signalR!.stop();
    }
  }
}

2. 使用SignalR客户端

在你的主Dart文件(例如main.dart)中,使用这个SignalR客户端来处理UI和与SignalR服务器的通信。

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

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

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

class _MyAppState extends State<MyApp> {
  final SignalRClient _signalRClient = SignalRClient(url: 'https://your-signalr-server-url');
  final TextEditingController _messageController = TextEditingController();
  final List<String> _messages = [];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter SignalR Demo'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            children: <Widget>[
              Expanded(
                child: ListView.builder(
                  itemCount: _messages.length,
                  itemBuilder: (context, index) {
                    return ListTile(
                      title: Text(_messages[index]),
                    );
                  },
                ),
              ),
              TextField(
                controller: _messageController,
                decoration: InputDecoration(
                  border: OutlineInputBorder(),
                  labelText: 'Message',
                ),
              ),
              ElevatedButton(
                onPressed: () {
                  _sendMessage();
                },
                child: Text('Send'),
              ),
            ],
          ),
        ),
      ),
    );
  }

  void _sendMessage() {
    String message = _messageController.text;
    _signalRClient.sendMessage(message);
    _messages.add("You: $message");
    setState(() {}); // 更新UI以显示新消息
    _messageController.clear();
  }

  @override
  void dispose() {
    _signalRClient.disconnect();
    super.dispose();
  }
}

注意事项

  1. SignalR服务器URL:确保你替换了SignalRClient中的URL为你自己的SignalR服务器URL。
  2. 错误处理:在实际应用中,你可能需要更健壮的错误处理和重连逻辑。
  3. UI更新:在_signalRClient.onReceive回调中,你可能需要使用setState或其他状态管理方法来更新UI,以显示接收到的消息。

这个示例展示了如何在Flutter应用中集成和使用signalr_socket插件进行实时通信。你可以根据需要进行扩展和修改。

回到顶部