Flutter SignalR通信插件signalr_netcore_plus的使用
Flutter SignalR通信插件signalr_netcore_plus的使用
A Flutter SignalR客户端用于 ASP.NET Core。
ASP.NET Core SignalR 是一个开源库,简化了向应用添加实时Web功能的过程。实时Web功能使服务器端代码能够即时向客户端推送内容。
该客户端经过测试与 ASP.NET Core 3.1 和 ASP .NET Core 6 兼容。
该客户端能够调用服务器端的Hub函数(包括流式处理函数),并接收由服务器发起的方法调用。它还支持自动重连功能。
该客户端支持以下传输协议:
- WebSocket
- Service Side Events
- Long Polling
该客户端支持以下Hub协议:
- Json
- MessagePack
示例
- Chat client/server - 一个简单的客户端/服务器聊天应用。
- Integration test app - 查看客户端如何调用各种类型的Hub函数。
开始使用
在 pubspec.yaml
文件中添加 signalr_netcore_plus
依赖项:
dependencies:
flutter:
sdk: flutter
signalr_netcore_plus:
重要提示:如果你遇到问题(例如收不到消息回调)与最新版本有关,请尝试使用较旧的版本如 signalr_netcore_plus: 0.1.7+2-nullsafety.3
,但请注意,该版本不支持自动重连功能,需要手动处理。
使用方法
让我们演示一些基本用法:
1. 创建Hub连接
// 导入库
import 'package:signalr_netcore_plus/signalr_client.dart';
// SignalR服务器的位置
final serverUrl = "192.168.10.50:51001";
// 使用HubConnectionBuilder创建连接
final hubConnection = HubConnectionBuilder().withUrl(serverUrl).build();
// 当连接关闭时,在控制台打印一条消息
hubConnection.onclose((error) => print("Connection Closed"));
日志记录可以通过 Dart 的 logging包 支持:
// 导入日志库
import 'package:logging/logging.dart';
import 'package:signalr_netcore_plus/signalr_client.dart';
// 配置日志
Logger.root.level = Level.ALL;
// 将日志写入控制台
Logger.root.onRecord.listen((LogRecord rec) {
print('${rec.level.name}: ${rec.time}: ${rec.message}');
});
// 如果只想记录高级别Hub协议的消息:
final hubProtLogger = Logger("SignalR - hub");
// 如果还想记录传输消息:
final transportProtLogger = Logger("SignalR - transport");
// SignalR服务器的位置
final serverUrl = "192.168.10.50:51001";
final httpOptions = HttpConnectionOptions(logger: transportProtLogger);
//final httpOptions = new HttpConnectionOptions(logger: transportProtLogger, transport: HttpTransportType.WebSockets); // 默认传输类型
//final httpOptions = new HttpConnectionOptions(logger: transportProtLogger, transport: HttpTransportType.ServerSentEvents);
//final httpOptions = new HttpConnectionOptions(logger: transportProtLogger, transport: HttpTransportType.LongPolling);
// 如果需要授权Hub连接,则提供一个异步回调函数,返回令牌字符串(见AccessTokenFactory类型定义)并分配给accessTokenFactory参数:
// final httpOptions = new HttpConnectionOptions(.... accessTokenFactory: () async => await getAccessToken());
// 使用HubConnectionBuilder创建连接
final hubConnection = HubConnectionBuilder().withUrl(serverUrl, options: httpOptions).configureLogging(hubProtLogger).build();
// 当连接关闭时,在控制台打印一条消息
hubConnection.onclose((error) => print("Connection Closed"));
2. 连接到Hub
调用以下方法开始握手并连接客户端到SignalR服务器
await hubConnection.start();
3. 调用Hub函数
假设有一个这样的Hub函数:
public string MethodOneSimpleParameterSimpleReturnValue(string p1)
{
Console.WriteLine($"'MethodOneSimpleParameterSimpleReturnValue' invoked. Parameter value: '{p1}");
return p1;
}
客户端可以使用以下方式调用该函数:
final result = await hubConnection.invoke("MethodOneSimpleParameterSimpleReturnValue", args: <Object>["ParameterValue"]);
logger.log(LogLevel.Information, "Result: '$result'");
4. 调用客户端函数
假设服务器调用了一个名为 “aClientProvidedFunction” 的函数:
await Clients.Caller.SendAsync("aClientProvidedFunction", null);
客户端提供该函数的方式如下:
hubConnection.on("aClientProvidedFunction", _handleAClientProvidedFunction);
// 注销函数
// a) 注销特定实现:
// hubConnection.off("aClientProvidedFunction", method: _handleServerInvokeMethodNoParametersNoReturnValue);
// b) 注销所有实现:
// hubConnection.off("aClientProvidedFunction");
...
void _handleAClientProvidedFunction(List<Object> parameters) {
logger.log(LogLevel.Information, "Server invoked the method");
}
5. 使用Msgpack进行序列化
Hub应在客户端和服务器上配置为使用Msgpack协议
客户端
import 'package:signalr_netcore_plus/msgpack_hub_protocol.dart';
_hubConnection = HubConnectionBuilder()
.withUrl(_serverUrl, options: httpOptions)
/* 配置Hub使用Msgpack协议 */
.withHubProtocol(MessagePackHubProtocol())
.withAutomaticReconnect()
.configureLogging(logger)
.withSingleListener(true)
.build();
服务器
在你的ASP NET核心项目中添加以下包
Microsoft.AspNetCore.SignalR.Protocols.MessagePack
public void ConfigureServices(IServiceCollection services)
{
// 配置Hub使用Msgpack协议
services.AddSignalR().AddMessagePackProtocol();
}
关于参数类型的注意事项
所有函数参数和返回值都通过使用dart:convert包(json.endcode/json.decode)进行序列化/反序列化。确保你:
- 只使用简单参数类型
- 或者
- 使用实现了toJson()方法的对象,因为该方法被dart:convert包用来序列化对象。
Flutter Json 101:
MSGPACK
所有函数参数和返回值都通过使用 msgpack_dart 包进行序列化/反序列化。确保你:
- 只使用简单参数类型
- 或者
- 将类转换为Map,并使用Json编码/解码后传递给Msgpack
- 或者
- 使用自定义编码器和解码器将消息序列化为字节,然后传递给SignalR
MSGPACK - 它像JSON一样,但更快更小
如何暴露一个MessageHeaders对象以便客户端可以发送默认头部
代码示例:
final defaultHeaders = MessageHeaders();
defaultHeaders.setHeaderValue("HEADER_MOCK_1", "HEADER_VALUE_1");
defaultHeaders.setHeaderValue("HEADER_MOCK_2", "HEADER_VALUE_2");
final httpConnectionOptions = new HttpConnectionOptions(
httpClient: WebSupportingHttpClient(logger,
httpClientCreateCallback: _httpClientCreateCallback),
accessTokenFactory: () => Future.value('JWT_TOKEN'),
logger: logger,
logMessageContent: true,
headers: defaultHeaders);
final _hubConnection = HubConnectionBuilder()
.withUrl(_serverUrl, options: httpConnectionOptions)
.withAutomaticReconnect(retryDelays: [2000, 5000, 10000, 20000, null])
.configureLogging(logger)
.withSingleListener(true)
.build();
HTTP请求日志:
I/flutter ( 5248): Starting connection with transfer format 'TransferFormat.Text'.
I/flutter ( 5248): Sending negotiation request: https://localhost:5000/negotiate?negotiateVersion=1
I/flutter ( 5248): HTTP send: url 'https://localhost:5000/negotiate?negotiateVersion=1', method: 'POST' content: '' content length = '0'
headers: '{ content-type: text/plain;charset=UTF-8 }, { HEADER_MOCK_1: HEADER_VALUE_1 }, { X-Requested-With: FlutterHttpClient }, { HEADER_MOCK_2: HEADER_VALUE_2 }, { Authorization: Bearer JWT_TOKEN }'
示例代码
import 'app.dart';
import 'package:flutter/material.dart';
const kChatServerUrl = "http://192.168.0.4:5000";
void main() {
runApp(App());
}
更多关于Flutter SignalR通信插件signalr_netcore_plus的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter SignalR通信插件signalr_netcore_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用signalr_netcore_plus
插件进行SignalR通信的示例代码。signalr_netcore_plus
是一个用于Flutter的SignalR客户端库,允许你与ASP.NET Core SignalR服务器进行通信。
1. 添加依赖
首先,在你的pubspec.yaml
文件中添加signalr_netcore_plus
依赖:
dependencies:
flutter:
sdk: flutter
signalr_netcore_plus: ^x.y.z # 请替换为最新版本号
然后运行flutter pub get
来获取依赖。
2. 配置SignalR连接
在你的Flutter项目中,创建一个新的Dart文件(例如signalr_service.dart
)来配置和管理SignalR连接。
import 'package:flutter/material.dart';
import 'package:signalr_netcore_plus/signalr_netcore_plus.dart';
class SignalRService {
late HubConnection _hubConnection;
SignalRService() {
_initSignalR();
}
void _initSignalR() async {
_hubConnection = HubConnectionBuilder()
.withUrl('https://your-signalr-server-url/your-hub-endpoint')
.withAutomaticReconnect()
.build();
_hubConnection.onclose((error) async {
print('Connection closed with error: ${error?.message}');
await startConnection();
});
await startConnection();
}
Future<void> startConnection() async {
try {
await _hubConnection.start();
print('Connected to SignalR server');
} catch (e) {
print('Error while connecting to SignalR server: $e');
}
}
Future<void> sendMessage(String message) async {
if (_hubConnection.state == HubConnectionState.connected) {
await _hubConnection.invoke('SendMessage', message);
} else {
print('Not connected to SignalR server');
}
}
Stream<String> onReceiveMessage() {
return _hubConnection.on<String>('ReceiveMessage');
}
}
3. 使用SignalR服务
在你的Flutter UI中,使用SignalRService
来处理SignalR通信。以下是一个简单的示例,展示如何发送和接收消息。
import 'package:flutter/material.dart';
import 'signalr_service.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final SignalRService signalRService = SignalRService();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter SignalR Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
decoration: InputDecoration(labelText: 'Message'),
onSubmitted: (message) {
signalRService.sendMessage(message);
},
),
SizedBox(height: 16),
Expanded(
child: StreamBuilder<String>(
stream: signalRService.onReceiveMessage(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(
'Received: ${snapshot.data!}',
style: TextStyle(fontSize: 18),
);
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error!}');
}
return Center(child: CircularProgressIndicator());
},
),
),
],
),
),
),
);
}
}
4. 运行应用
确保你的ASP.NET Core SignalR服务器正在运行,并且URL和Hub名称与代码中配置的相匹配。然后运行你的Flutter应用,你应该能够通过UI发送消息到服务器,并接收来自服务器的消息。
这个示例展示了如何使用signalr_netcore_plus
插件在Flutter应用中建立和管理SignalR连接,发送和接收消息。根据你的实际需求,你可以进一步扩展和定制这个示例。