Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hub callback bug fixes & invokeMethod improvements #12

Merged
merged 12 commits into from
Jan 20, 2021
19 changes: 19 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "signalr_flutter",
"request": "launch",
"type": "dart"
},
{
"name": "example",
"cwd": "example",
"request": "launch",
"type": "dart"
}
]
}
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,33 @@
## 0.0.5

* Fixed a bug where invokeMethod only accepting string as return value

## 0.0.6-dev.1

* Possible fix for callbacks throwing exception about type mismatch.
* invokeMethod now has generic return type & upto 10 arguments support.

## 0.0.6-dev.2

* HubCallBack function now returns the value as well as the subscribed method name.
* invokeMethod now can take as many arguments as you want.

## 0.0.6-dev.3

* Possible fix for ios Hub events not returning

## 0.1.0-dev.1

* Fix for ios Hub events not returning

## 0.1.0-dev.2

* Fixed Duplicated Hub events for ios.

## 0.1.0

* Fix a issue where hub callback only accepting strings.
* Hub callback now returns the message as well as the subscribed method name.
* Made invokeMethod generic.
* As many arguments as you want in invokeMethod.
* fix for ios Hub events not working.
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,21 @@ First of all, Initialize SignalR and connect to your server.
SignalR signalR = SignalR(
'<Your server url here>',
"<Your hub name here>",
hubMethods: ["<Your Hub Method Names>"]
statusChangeCallback: (status) => print(status),
hubCallback: (message) => print(message));
hubCallback: (methodName, message) => print('MethodName = $methodName, Message = $message'));
signalR.connect();
```

Here `statusChangeCallback` will get called whenever connection status with server changes.

`hubCallback` will receive calls from the server if you subscribe to any hub method. You can do that with,
`hubCallback` will receive calls from the server if you subscribe to any hub method. You can do that with `hubMethods`.

`hubMethods` are the hub method names you want to subscribe.

```dart
signalR.subscribeToHubMethod("methodName");
```
There is a `headers` parameters also which takes a `Map<String, String>`.

You can also invoke any server method.
Note: `arguments` list can have maximum number of five elements.

```dart
signalR.invokeMethod("<Your method name here>", arguments: ["argument1", "argument2"]);
Expand Down
4 changes: 2 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ group 'dev.asdevs.signalr_flutter'
version '1.0-SNAPSHOT'

buildscript {
ext.kotlin_version = '1.4.0'
ext.kotlin_version = '1.4.10'
repositories {
google()
jcenter()
}

dependencies {
classpath 'com.android.tools.build:gradle:4.0.1'
classpath 'com.android.tools.build:gradle:4.1.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Expand Down
26 changes: 13 additions & 13 deletions android/src/main/kotlin/dev/asdevs/signalr_flutter/SignalR.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ object SignalR {
private lateinit var connection: HubConnection
private lateinit var hub: HubProxy

fun connectToServer(url: String, hubName: String, queryString: String, headers: Map<String, String>, transport: Int, result: Result) {
fun connectToServer(url: String, hubName: String, queryString: String, headers: Map<String, String>, transport: Int, hubMethods: List<String>, result: Result) {
try {
connection = if (queryString.isEmpty()) {
HubConnection(url)
Expand All @@ -38,6 +38,14 @@ object SignalR {
}
hub = connection.createHubProxy(hubName)

hubMethods.forEach { methodName ->
hub.on(methodName, { res ->
android.os.Handler(Looper.getMainLooper()).post {
SignalRFlutterPlugin.channel.invokeMethod("NewMessage", listOf(methodName, res))
}
}, Any::class.java)
}

connection.connected {
android.os.Handler(Looper.getMainLooper()).post {
SignalRFlutterPlugin.channel.invokeMethod("ConnectionStatus", connection.state.name)
Expand Down Expand Up @@ -106,27 +114,19 @@ object SignalR {

fun listenToHubMethod(methodName: String, result: Result) {
try {
hub.on<String>(methodName, { res ->
hub.on(methodName, { res ->
android.os.Handler(Looper.getMainLooper()).post {
SignalRFlutterPlugin.channel.invokeMethod("NewMessage", res)
SignalRFlutterPlugin.channel.invokeMethod("NewMessage", listOf(methodName, res))
}
}, String::class.java)
}, Any::class.java)
} catch (ex: Exception) {
result.error("Error", ex.localizedMessage, null)
}
}

fun invokeServerMethod(methodName: String, args: List<Any>, result: Result) {
try {
val res: SignalRFuture<Any> = when (args.count()) {
0 -> hub.invoke(Any::class.java, methodName)
1 -> hub.invoke(Any::class.java, methodName, args[0])
2 -> hub.invoke(Any::class.java, methodName, args[0], args[1])
3 -> hub.invoke(Any::class.java, methodName, args[0], args[1], args[2])
4 -> hub.invoke(Any::class.java, methodName, args[0], args[1], args[2], args[3])
5 -> hub.invoke(Any::class.java, methodName, args[0], args[1], args[2], args[3], args[4])
else -> throw Exception("Maximum 5 arguments supported. Your arguments List count is ${args.count()}.")
}
val res: SignalRFuture<Any> = hub.invoke(Any::class.java, methodName, *args.toTypedArray())

res.done { msg: Any? ->
android.os.Handler(Looper.getMainLooper()).post {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,14 @@ public class SignalRFlutterPlugin : FlutterPlugin, MethodCallHandler {
CallMethod.ConnectToServer.value -> {
val arguments = call.arguments as Map<*, *>
@Suppress("UNCHECKED_CAST")
SignalR.connectToServer(arguments["baseUrl"] as String, arguments["hubName"] as String, arguments["queryString"] as String,
arguments["headers"] as? Map<String, String>
?: emptyMap(), arguments["transport"] as Int, result)
SignalR.connectToServer(
arguments["baseUrl"] as String,
arguments["hubName"] as String,
arguments["queryString"] as String,
arguments["headers"] as? Map<String, String> ?: emptyMap(),
arguments["transport"] as Int,
arguments["hubMethods"] as? List<String> ?: emptyList(),
result)
}
CallMethod.Reconnect.value -> {
SignalR.reconnect(result)
Expand Down
2 changes: 1 addition & 1 deletion example/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:4.0.1'
classpath 'com.android.tools.build:gradle:4.1.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Expand Down
4 changes: 2 additions & 2 deletions example/android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Sun Aug 23 12:55:54 IST 2020
#Sun Oct 25 12:57:53 IST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
32 changes: 13 additions & 19 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ class _MyAppState extends State<MyApp> {

// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
signalR = SignalR(
'<Your url here>', "<Your hubname here>",
statusChangeCallback: _onStatusChange, hubCallback: _onNewMessage);
signalR = SignalR('<Your SignalR Url>', "<Your Hub Name>",
hubMethods: ["<Hub Method Name>"],
statusChangeCallback: _onStatusChange,
hubCallback: _onNewMessage);
}

@override
Expand All @@ -47,12 +48,6 @@ class _MyAppState extends State<MyApp> {
padding: const EdgeInsets.only(top: 20.0),
child: RaisedButton(
onPressed: _buttonTapped, child: Text("Invoke Method")),
),
Padding(
padding: const EdgeInsets.only(top: 20.0),
child: RaisedButton(
onPressed: () => signalR.subscribeToHubMethod("methodName"),
child: Text("Listen to Hub Method")),
)
],
),
Expand All @@ -67,25 +62,24 @@ class _MyAppState extends State<MyApp> {
);
}

_onStatusChange(String status) {
_onStatusChange(dynamic status) {
if (mounted) {
setState(() {
_signalRStatus = status;
_signalRStatus = status as String;
});
}
}

_onNewMessage(dynamic message) {
print(message);
_onNewMessage(String methodName, dynamic message) {
print('MethodName = $methodName, Message = $message');
}

_buttonTapped() async {
final res = await signalR
.invokeMethod("<Your methodname here>", arguments: ['<Your arguments here>']).catchError((error) {
print(error.toString());
});
final snackBar =
SnackBar(content: Text('SignalR Method Response: ${res.toString()}'));
final res = await signalR.invokeMethod<dynamic>("<Your Method Name>",
arguments: ["<Your Method Arguments>"]).catchError((error) {
print(error.toString());
});
final snackBar = SnackBar(content: Text('SignalR Method Response: $res'));
_scaffoldKey.currentState.showSnackBar(snackBar);
}
}
Loading