├── ios
├── Assets
│ ├── .gitkeep
│ └── SwiftR.js
├── Classes
│ ├── SignalrFlutterPlugin.h
│ ├── signalr_flutter.h
│ ├── SignalrFlutterPlugin.m
│ ├── SignalrApi.h
│ ├── SwiftSignalrFlutterPlugin.swift
│ ├── SignalrApi.m
│ └── SwiftR.swift
├── .gitignore
└── signalr_flutter.podspec
├── .gitignore
├── example
├── ios
│ ├── Runner
│ │ ├── Runner-Bridging-Header.h
│ │ ├── Assets.xcassets
│ │ │ ├── LaunchImage.imageset
│ │ │ │ ├── LaunchImage.png
│ │ │ │ ├── LaunchImage@2x.png
│ │ │ │ ├── LaunchImage@3x.png
│ │ │ │ ├── README.md
│ │ │ │ └── Contents.json
│ │ │ └── AppIcon.appiconset
│ │ │ │ ├── Icon-App-20x20@1x.png
│ │ │ │ ├── Icon-App-20x20@2x.png
│ │ │ │ ├── Icon-App-20x20@3x.png
│ │ │ │ ├── Icon-App-29x29@1x.png
│ │ │ │ ├── Icon-App-29x29@2x.png
│ │ │ │ ├── Icon-App-29x29@3x.png
│ │ │ │ ├── Icon-App-40x40@1x.png
│ │ │ │ ├── Icon-App-40x40@2x.png
│ │ │ │ ├── Icon-App-40x40@3x.png
│ │ │ │ ├── Icon-App-60x60@2x.png
│ │ │ │ ├── Icon-App-60x60@3x.png
│ │ │ │ ├── Icon-App-76x76@1x.png
│ │ │ │ ├── Icon-App-76x76@2x.png
│ │ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ │ ├── Icon-App-83.5x83.5@2x.png
│ │ │ │ └── Contents.json
│ │ ├── AppDelegate.swift
│ │ ├── Base.lproj
│ │ │ ├── Main.storyboard
│ │ │ └── LaunchScreen.storyboard
│ │ └── Info.plist
│ ├── Flutter
│ │ ├── Debug.xcconfig
│ │ ├── Release.xcconfig
│ │ └── AppFrameworkInfo.plist
│ ├── Runner.xcodeproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ ├── WorkspaceSettings.xcsettings
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ ├── xcshareddata
│ │ │ └── xcschemes
│ │ │ │ └── Runner.xcscheme
│ │ └── project.pbxproj
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── WorkspaceSettings.xcsettings
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── Podfile.lock
│ ├── .gitignore
│ └── Podfile
├── android
│ ├── gradle.properties
│ ├── app
│ │ ├── src
│ │ │ ├── main
│ │ │ │ ├── res
│ │ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── drawable
│ │ │ │ │ │ └── launch_background.xml
│ │ │ │ │ ├── drawable-v21
│ │ │ │ │ │ └── launch_background.xml
│ │ │ │ │ ├── values
│ │ │ │ │ │ └── styles.xml
│ │ │ │ │ └── values-night
│ │ │ │ │ │ └── styles.xml
│ │ │ │ ├── kotlin
│ │ │ │ │ └── dev
│ │ │ │ │ │ └── asdevs
│ │ │ │ │ │ └── signalr_flutter_example
│ │ │ │ │ │ └── MainActivity.kt
│ │ │ │ └── AndroidManifest.xml
│ │ │ ├── debug
│ │ │ │ └── AndroidManifest.xml
│ │ │ └── profile
│ │ │ │ └── AndroidManifest.xml
│ │ └── build.gradle
│ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.properties
│ ├── .gitignore
│ ├── build.gradle
│ └── settings.gradle
├── .metadata
├── README.md
├── .gitignore
├── test
│ └── widget_test.dart
├── analysis_options.yaml
├── pubspec.yaml
├── lib
│ └── main.dart
└── pubspec.lock
├── android
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ └── dev
│ │ │ └── asdevs
│ │ │ └── signalr_flutter
│ │ │ └── SignalRFlutterPlugin.kt
│ │ └── java
│ │ └── dev
│ │ └── asdevs
│ │ └── signalr_flutter
│ │ └── SignalrApi.java
├── gradle.properties
├── libraries
│ ├── signalr-client-sdk.jar
│ └── signalr-client-sdk-android.jar
├── .gitignore
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── settings.gradle
└── build.gradle
├── analysis_options.yaml
├── .idea
├── runConfigurations
│ └── example_lib_main_dart.xml
├── modules.xml
├── libraries
│ └── Dart_SDK.xml
└── workspace.xml
├── .metadata
├── run_pigeon.sh
├── test
└── signalr_flutter_test.dart
├── signalr_flutter.iml
├── LICENSE
├── pubspec.yaml
├── .vscode
└── launch.json
├── pigeons
└── signalr_api.dart
├── README.md
├── lib
├── signalr_platform_interface.dart
├── signalr_flutter.dart
└── signalr_api.dart
├── CHANGELOG.md
└── pubspec.lock
/ios/Assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .dart_tool/
3 |
4 | .packages
5 | .pub/
6 |
7 | build/
8 |
--------------------------------------------------------------------------------
/example/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/android/libraries/signalr-client-sdk.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/android/libraries/signalr-client-sdk.jar
--------------------------------------------------------------------------------
/ios/Classes/SignalrFlutterPlugin.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface SignalrFlutterPlugin : NSObject
4 | @end
5 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/android/libraries/signalr-client-sdk-android.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/android/libraries/signalr-client-sdk-android.jar
--------------------------------------------------------------------------------
/ios/Classes/signalr_flutter.h:
--------------------------------------------------------------------------------
1 | //
2 | // signalr_flutter.h
3 | // signalr_flutter
4 | //
5 | // Created by Ayon Das on 07/11/21.
6 | //
7 |
8 | #import "SignalrApi.h"
9 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:flutter_lints/flutter.yaml
2 |
3 | # Additional information about this file can be found at
4 | # https://dart.dev/guides/language/analysis-options
5 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AS-Devs/signalr_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/app/src/main/kotlin/dev/asdevs/signalr_flutter_example/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package dev.asdevs.signalr_flutter_example
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
6 |
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
7 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/example_lib_main_dart.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 18116933e77adc82f80866c928266a5b4f1ed645
8 | channel: stable
9 |
10 | project_type: plugin
11 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/example/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/example/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 18116933e77adc82f80866c928266a5b4f1ed645
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/example/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 | **/*.keystore
13 | **/*.jks
14 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 |
3 | repositories {
4 | google()
5 | mavenCentral()
6 | gradlePluginPortal()
7 | }
8 | }
9 |
10 | plugins {
11 | id "com.android.library" version "8.1.0" apply false
12 | id "org.jetbrains.kotlin.android" version "1.8.22" apply false
13 | }
14 |
15 | rootProject.name = 'signalr_flutter'
16 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | allprojects {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | }
6 | }
7 |
8 | rootProject.buildDir = '../build'
9 | subprojects {
10 | project.buildDir = "${rootProject.buildDir}/${project.name}"
11 | project.evaluationDependsOn(':app')
12 | }
13 |
14 | tasks.register("clean", Delete) {
15 | delete rootProject.buildDir
16 | }
17 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/run_pigeon.sh:
--------------------------------------------------------------------------------
1 | # Run this file to regenerate pigeon files
2 | flutter pub run pigeon \
3 | --input pigeons/signalr_api.dart \
4 | --dart_out lib/signalr_api.dart \
5 | --objc_header_out ios/Classes/SignalrApi.h \
6 | --objc_source_out ios/Classes/SignalrApi.m \
7 | --objc_prefix FLT \
8 | --java_out android/src/main/java/dev/asdevs/signalr_flutter/SignalrApi.java \
9 | --java_package "dev.asdevs.signalr_flutter"
--------------------------------------------------------------------------------
/example/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .vagrant/
3 | .sconsign.dblite
4 | .svn/
5 |
6 | .DS_Store
7 | *.swp
8 | profile
9 |
10 | DerivedData/
11 | build/
12 | GeneratedPluginRegistrant.h
13 | GeneratedPluginRegistrant.m
14 |
15 | .generated/
16 |
17 | *.pbxuser
18 | *.mode1v3
19 | *.mode2v3
20 | *.perspectivev3
21 |
22 | !default.pbxuser
23 | !default.mode1v3
24 | !default.mode2v3
25 | !default.perspectivev3
26 |
27 | xcuserdata
28 |
29 | *.moved-aside
30 |
31 | *.pyc
32 | *sync/
33 | Icon?
34 | .tags*
35 |
36 | /Flutter/Generated.xcconfig
37 | /Flutter/ephemeral/
38 | /Flutter/flutter_export_environment.sh
--------------------------------------------------------------------------------
/example/ios/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Flutter (1.0.0)
3 | - signalr_flutter (0.0.1):
4 | - Flutter
5 |
6 | DEPENDENCIES:
7 | - Flutter (from `Flutter`)
8 | - signalr_flutter (from `.symlinks/plugins/signalr_flutter/ios`)
9 |
10 | EXTERNAL SOURCES:
11 | Flutter:
12 | :path: Flutter
13 | signalr_flutter:
14 | :path: ".symlinks/plugins/signalr_flutter/ios"
15 |
16 | SPEC CHECKSUMS:
17 | Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
18 | signalr_flutter: fcbc21129947f1f53e38b6b035012aa150359bc8
19 |
20 | PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3
21 |
22 | COCOAPODS: 1.11.3
23 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # signalr_flutter_example
2 |
3 | Demonstrates how to use the signalr_flutter plugin.
4 |
5 | ## Getting Started
6 |
7 | This project is a starting point for a Flutter application.
8 |
9 | A few resources to get you started if this is your first Flutter project:
10 |
11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
13 |
14 | For help getting started with Flutter, view our
15 | [online documentation](https://flutter.dev/docs), which offers tutorials,
16 | samples, guidance on mobile development, and a full API reference.
17 |
--------------------------------------------------------------------------------
/ios/Classes/SignalrFlutterPlugin.m:
--------------------------------------------------------------------------------
1 | #import "SignalrFlutterPlugin.h"
2 | #if __has_include()
3 | #import
4 | #else
5 | // Support project import fallback if the generated compatibility header
6 | // is not copied when this plugin is created as a library.
7 | // https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816
8 | #import "signalr_flutter-Swift.h"
9 | #endif
10 |
11 | @implementation SignalrFlutterPlugin
12 | + (void)registerWithRegistrar:(NSObject*)registrar {
13 | [SwiftSignalrFlutterPlugin registerWithRegistrar:registrar];
14 | }
15 | @end
16 |
--------------------------------------------------------------------------------
/example/ios/.gitignore:
--------------------------------------------------------------------------------
1 | **/dgph
2 | *.mode1v3
3 | *.mode2v3
4 | *.moved-aside
5 | *.pbxuser
6 | *.perspectivev3
7 | **/*sync/
8 | .sconsign.dblite
9 | .tags*
10 | **/.vagrant/
11 | **/DerivedData/
12 | Icon?
13 | **/Pods/
14 | **/.symlinks/
15 | profile
16 | xcuserdata
17 | **/.generated/
18 | Flutter/App.framework
19 | Flutter/Flutter.framework
20 | Flutter/Flutter.podspec
21 | Flutter/Generated.xcconfig
22 | Flutter/ephemeral/
23 | Flutter/app.flx
24 | Flutter/app.zip
25 | Flutter/flutter_assets/
26 | Flutter/flutter_export_environment.sh
27 | ServiceDefinitions.json
28 | Runner/GeneratedPluginRegistrant.*
29 |
30 | # Exceptions to above rules.
31 | !default.mode1v3
32 | !default.mode2v3
33 | !default.pbxuser
34 | !default.perspectivev3
35 |
--------------------------------------------------------------------------------
/test/signalr_flutter_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/services.dart';
2 | import 'package:flutter_test/flutter_test.dart';
3 |
4 | void main() {
5 | const MethodChannel channel = MethodChannel('signalr_flutter');
6 |
7 | setUpAll(() {
8 | TestWidgetsFlutterBinding.ensureInitialized();
9 | });
10 |
11 | setUp(() {
12 | TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
13 | .setMockMethodCallHandler(channel, (MethodCall methodCall) async {
14 | return '42';
15 | });
16 | });
17 |
18 | tearDown(() {
19 | TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
20 | .setMockMethodCallHandler(channel, null);
21 | });
22 |
23 | test('getPlatformVersion', () async {});
24 | }
25 |
--------------------------------------------------------------------------------
/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | def flutterSdkPath = {
3 | def properties = new Properties()
4 | file("local.properties").withInputStream { properties.load(it) }
5 | def flutterSdkPath = properties.getProperty("flutter.sdk")
6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
7 | return flutterSdkPath
8 | }()
9 |
10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
11 |
12 | repositories {
13 | google()
14 | mavenCentral()
15 | gradlePluginPortal()
16 | }
17 | }
18 |
19 | plugins {
20 | id "dev.flutter.flutter-plugin-loader" version "1.0.0"
21 | id "com.android.application" version "8.1.0" apply false
22 | id "org.jetbrains.kotlin.android" version "1.8.22" apply false
23 | }
24 |
25 | include ':app'
--------------------------------------------------------------------------------
/example/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 11.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | **/ios/Flutter/.last_build_id
26 | .dart_tool/
27 | .flutter-plugins
28 | .flutter-plugins-dependencies
29 | .packages
30 | .pub-cache/
31 | .pub/
32 | /build/
33 |
34 | # Web related
35 | lib/generated_plugin_registrant.dart
36 |
37 | # Symbolication related
38 | app.*.symbols
39 |
40 | # Obfuscation related
41 | app.*.map.json
42 |
43 | # Android Studio will place build artifacts here
44 | /android/app/debug
45 | /android/app/profile
46 | /android/app/release
47 |
--------------------------------------------------------------------------------
/.idea/libraries/Dart_SDK.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id "com.android.library"
3 | id "kotlin-android"
4 | }
5 |
6 | group 'dev.asdevs.signalr_flutter'
7 | version '1.0-SNAPSHOT'
8 |
9 | rootProject.allprojects {
10 | repositories {
11 | google()
12 | mavenCentral()
13 | }
14 | }
15 |
16 | android {
17 | namespace 'dev.asdevs.signalr_flutter'
18 | compileOptions {
19 | sourceCompatibility JavaVersion.VERSION_17
20 | targetCompatibility JavaVersion.VERSION_17
21 | }
22 |
23 | kotlinOptions {
24 | jvmTarget = '17'
25 | }
26 |
27 | sourceSets {
28 | main.java.srcDirs += 'src/main/kotlin'
29 | }
30 |
31 | defaultConfig {
32 | compileSdk 33
33 | minSdkVersion 21
34 | }
35 | }
36 |
37 | dependencies {
38 | implementation 'com.google.code.gson:gson:2.8.9'
39 | implementation files('libraries/signalr-client-sdk.jar')
40 | implementation files('libraries/signalr-client-sdk-android.jar')
41 | }
42 |
--------------------------------------------------------------------------------
/signalr_flutter.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/example/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility that Flutter provides. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:signalr_flutter_example/main.dart';
12 |
13 | void main() {
14 | testWidgets('Verify Platform version', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | await tester.pumpWidget(const MyApp());
17 |
18 | // Verify that platform version is retrieved.
19 | expect(
20 | find.byWidgetPredicate(
21 | (Widget widget) =>
22 | widget is Text && widget.data!.startsWith('Running on:'),
23 | ),
24 | findsOneWidget,
25 | );
26 | });
27 | }
28 |
--------------------------------------------------------------------------------
/ios/signalr_flutter.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
3 | # Run `pod lib lint signalr_flutter.podspec` to validate before publishing.
4 | #
5 | Pod::Spec.new do |s|
6 | s.name = 'signalr_flutter'
7 | s.version = '0.0.1'
8 | s.summary = 'A new flutter plugin project.'
9 | s.description = <<-DESC
10 | A new flutter plugin project.
11 | DESC
12 | s.homepage = 'https://github.com/AS-Devs/signalr_flutter'
13 | s.license = { :file => '../LICENSE' }
14 | s.author = { 'Ayon Das' => 'ayantorres@gmail.com' }
15 | s.source = { :path => '.' }
16 | s.source_files = 'Classes/**/*'
17 | s.resources = 'Assets/**/*.js'
18 | s.dependency 'Flutter'
19 | s.platform = :ios, '8.0'
20 |
21 | # Flutter.framework does not contain a i386 slice.
22 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
23 | s.swift_version = '5.0'
24 | end
25 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Ayon Das
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: signalr_flutter
2 | description: A flutter plugin for .net SignalR client. This client is for ASP.Net SignalR, not for .Net Core SignalR.
3 | version: 0.2.1
4 | repository: https://github.com/AS-Devs/signalr_flutter
5 | issue_tracker: https://github.com/AS-Devs/signalr_flutter/issues
6 |
7 | environment:
8 | flutter: ">=3.19.0"
9 | sdk: ">=3.2.0 <4.0.0"
10 |
11 | dependencies:
12 | flutter:
13 | sdk: flutter
14 |
15 | dev_dependencies:
16 | flutter_test:
17 | sdk: flutter
18 | flutter_lints: ^6.0.0
19 | pigeon: ^4.2.5
20 |
21 | # For information on the generic Dart part of this file, see the
22 | # following page: https://dart.dev/tools/pub/pubspec
23 |
24 | # The following section is specific to Flutter.
25 | flutter:
26 | # This section identifies this Flutter project as a plugin project.
27 | # The 'pluginClass' and Android 'package' identifiers should not ordinarily
28 | # be modified. They are used by the tooling to maintain consistency when
29 | # adding or updating assets for this project.
30 | plugin:
31 | platforms:
32 | android:
33 | package: dev.asdevs.signalr_flutter
34 | pluginClass: SignalrFlutterPlugin
35 | ios:
36 | pluginClass: SignalrFlutterPlugin
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "signalr_flutter",
9 | "request": "launch",
10 | "type": "dart"
11 | },
12 | {
13 | "name": "signalr_flutter (profile mode)",
14 | "request": "launch",
15 | "type": "dart",
16 | "flutterMode": "profile"
17 | },
18 | {
19 | "name": "signalr_flutter (release mode)",
20 | "request": "launch",
21 | "type": "dart",
22 | "flutterMode": "release"
23 | },
24 | {
25 | "name": "example",
26 | "cwd": "example",
27 | "request": "launch",
28 | "type": "dart"
29 | },
30 | {
31 | "name": "example (profile mode)",
32 | "cwd": "example",
33 | "request": "launch",
34 | "type": "dart",
35 | "flutterMode": "profile"
36 | },
37 | {
38 | "name": "example (release mode)",
39 | "cwd": "example",
40 | "request": "launch",
41 | "type": "dart",
42 | "flutterMode": "release"
43 | }
44 | ]
45 | }
--------------------------------------------------------------------------------
/example/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '11.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | use_frameworks!
32 | use_modular_headers!
33 |
34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
35 | end
36 |
37 | post_install do |installer|
38 | installer.pods_project.targets.each do |target|
39 | flutter_additional_ios_build_settings(target)
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/example/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # This file configures the analyzer, which statically analyzes Dart code to
2 | # check for errors, warnings, and lints.
3 | #
4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6 | # invoked from the command line by running `flutter analyze`.
7 |
8 | # The following line activates a set of recommended lints for Flutter apps,
9 | # packages, and plugins designed to encourage good coding practices.
10 | include: package:flutter_lints/flutter.yaml
11 |
12 | linter:
13 | # The lint rules applied to this project can be customized in the
14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml`
15 | # included above or to enable additional rules. A list of all available lints
16 | # and their documentation is published at
17 | # https://dart-lang.github.io/linter/lints/index.html.
18 | #
19 | # Instead of disabling a lint rule for the entire project in the
20 | # section below, it can also be suppressed for a single line of code
21 | # or a specific dart file by using the `// ignore: name_of_lint` and
22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file
23 | # producing the lint.
24 | rules:
25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule
26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
27 |
28 | # Additional information about this file can be found at
29 | # https://dart.dev/guides/language/analysis-options
30 |
--------------------------------------------------------------------------------
/pigeons/signalr_api.dart:
--------------------------------------------------------------------------------
1 | import 'package:pigeon/pigeon.dart';
2 |
3 | /// Transport method of the signalr connection.
4 | enum Transport { auto, serverSentEvents, longPolling }
5 |
6 | /// SignalR connection status
7 | enum ConnectionStatus {
8 | connecting,
9 | connected,
10 | reconnecting,
11 | disconnected,
12 | connectionSlow,
13 | connectionError
14 | }
15 |
16 | class ConnectionOptions {
17 | String? baseUrl;
18 | String? hubName;
19 | String? queryString;
20 | List? hubMethods;
21 | Map? headers;
22 | Transport? transport;
23 | }
24 |
25 | class StatusChangeResult {
26 | String? connectionId;
27 | ConnectionStatus? status;
28 | String? errorMessage;
29 | }
30 |
31 | @HostApi()
32 | abstract class SignalRHostApi {
33 | @async
34 | String connect(ConnectionOptions connectionOptions);
35 |
36 | @async
37 | String reconnect();
38 |
39 | @async
40 | void stop();
41 |
42 | @async
43 | bool isConnected();
44 |
45 | @async
46 | String invokeMethod(String methodName, List arguments);
47 | }
48 |
49 | @FlutterApi()
50 | abstract class SignalRPlatformApi {
51 | @async
52 | void onStatusChange(StatusChangeResult statusChangeResult);
53 |
54 | @async
55 | void onNewMessage(String hubName, String message);
56 | }
57 |
58 | void configurePigeon(PigeonOptions opts) {
59 | opts = const PigeonOptions(
60 | input: 'pigeons/signalr_api.dart',
61 | dartOut: '../lib/signalr_api.dart',
62 | objcHeaderOut: 'ios/Classes/signalr_api.h',
63 | objcSourceOut: 'ios/Classes/signalr_api.m',
64 | javaOut: 'android/src/main/java/dev/asdevs/signalr_flutter/Signalr_Api.java',
65 | );
66 | }
67 |
--------------------------------------------------------------------------------
/example/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id "com.android.application"
3 | id "kotlin-android"
4 | id "dev.flutter.flutter-gradle-plugin"
5 | }
6 |
7 |
8 | def localProperties = new Properties()
9 | def localPropertiesFile = rootProject.file('local.properties')
10 | if (localPropertiesFile.exists()) {
11 | localPropertiesFile.withReader('UTF-8') { reader ->
12 | localProperties.load(reader)
13 | }
14 | }
15 |
16 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
17 | if (flutterVersionCode == null) {
18 | flutterVersionCode = '1'
19 | }
20 |
21 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
22 | if (flutterVersionName == null) {
23 | flutterVersionName = '1.0'
24 | }
25 |
26 | android {
27 | namespace "dev.asdevs.signalr_flutter_example"
28 |
29 | compileOptions {
30 | sourceCompatibility JavaVersion.VERSION_17
31 | targetCompatibility JavaVersion.VERSION_17
32 | }
33 |
34 | kotlinOptions {
35 | jvmTarget = '17'
36 | }
37 |
38 | sourceSets {
39 | main.java.srcDirs += 'src/main/kotlin'
40 | }
41 |
42 | defaultConfig {
43 | applicationId "dev.asdevs.signalr_flutter_example"
44 | compileSdk 33
45 | minSdkVersion 21
46 | targetSdkVersion 33
47 | versionCode flutterVersionCode.toInteger()
48 | versionName flutterVersionName
49 | }
50 |
51 | buildTypes {
52 | release {
53 | // Signing with the debug keys for now, so `flutter run --release` works.
54 | signingConfig signingConfigs.debug
55 | }
56 | }
57 | }
58 |
59 | flutter {
60 | source '../..'
61 | }
62 |
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # signalr_flutter
2 |
3 | A flutter plugin for .net SignalR client.
4 |
5 | ## Usage
6 |
7 | First of all, Initialize SignalR and connect to your server.
8 |
9 | ```dart
10 | SignalR signalR = SignalR(
11 | '',
12 | "",
13 | hubMethods: [""]
14 | statusChangeCallback: (status) => print(status),
15 | hubCallback: (methodName, message) => print('MethodName = $methodName, Message = $message'));
16 | signalR.connect();
17 | ```
18 |
19 | Here `statusChangeCallback` will get called whenever connection status with server changes.
20 |
21 | `hubCallback` will receive calls from the server if you subscribe to any hub method. You can do that with `hubMethods`.
22 |
23 | `hubMethods` are the hub method names you want to subscribe.
24 |
25 | There is a `headers` parameters also which takes a `Map`.
26 |
27 | You can also invoke any server method.
28 |
29 | ```dart
30 | signalR.invokeMethod("", arguments: ["argument1", "argument2"]);
31 | ```
32 |
33 |
34 | If you are trying to connect with a HTTP url, then you need to add the following lines to the manifest of your android project.
35 |
36 | ```xml
37 |
39 |
40 | ```
41 |
42 | This is because of the [Network Security Config](https://developer.android.com/training/articles/security-config#CleartextTrafficPermitted).
43 |
44 | R8 may strip away some SignalR classes for the Android in Release Builds. Add the following line in your `proguard-rules.pro` file to solve this issue.
45 |
46 | `-keep class microsoft.aspnet.signalr.client.hubs.** { *; }`
47 |
48 |
49 | For more info check example.
50 |
51 | Any issue or PR is always welcome.
52 |
53 |
--------------------------------------------------------------------------------
/example/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | signalr_flutter_example
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 | CADisableMinimumFrameDurationOnPhone
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/lib/signalr_platform_interface.dart:
--------------------------------------------------------------------------------
1 | import 'package:signalr_flutter/signalr_api.dart';
2 |
3 | abstract class SignalrPlatformInterface {
4 | SignalrPlatformInterface(this.baseUrl, this.hubName,
5 | {this.queryString,
6 | this.headers,
7 | this.hubMethods,
8 | this.transport = Transport.auto,
9 | this.statusChangeCallback,
10 | this.hubCallback})
11 | : assert(baseUrl != ''),
12 | assert(hubName != '');
13 |
14 | final String baseUrl;
15 | final String hubName;
16 | final String? queryString;
17 |
18 | /// [Transport.Auto] is default.
19 | final Transport transport;
20 | final Map? headers;
21 |
22 | String? connectionId;
23 |
24 | /// List of Hub method names you want to subscribe. Every subsequent message from server gets called on [hubCallback].
25 | final List? hubMethods;
26 |
27 | /// This callback gets called whenever SignalR connection status with server changes.
28 | final void Function(ConnectionStatus?)? statusChangeCallback;
29 |
30 | /// This callback gets called whenever SignalR server sends some message to client.
31 | final void Function(String, String)? hubCallback;
32 |
33 | /// Connect to the SignalR Server with given [baseUrl] & [hubName].
34 | ///
35 | /// [queryString] is a optional field to send query to server.
36 | ///
37 | /// Returns the [connectionId].
38 | Future connect();
39 |
40 | /// Try to Reconnect SignalR connection if it gets disconnected.
41 | ///
42 | /// Returns the [connectionId]
43 | Future reconnect();
44 |
45 | /// Stops SignalR connection
46 | Future stop();
47 |
48 | /// Checks if SignalR connection is still active.
49 | ///
50 | /// Returns a boolean value
51 | Future isConnected();
52 |
53 | /// Invoke any server method with optional [arguments].
54 | Future invokeMethod(String methodName, {List? arguments});
55 | }
56 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: signalr_flutter_example
2 | description: Demonstrates how to use the signalr_flutter plugin.
3 | version: 1.1.0+1
4 |
5 | # The following line prevents the package from being accidentally published to
6 | # pub.dev using `flutter pub publish`. This is preferred for private packages.
7 | publish_to: "none" # Remove this line if you wish to publish to pub.dev
8 |
9 | environment:
10 | flutter: ">=3.19.0"
11 | sdk: ">=3.2.0"
12 |
13 | # Dependencies specify other packages that your package needs in order to work.
14 | # To automatically upgrade your package dependencies to the latest versions
15 | # consider running `flutter pub upgrade --major-versions`. Alternatively,
16 | # dependencies can be manually updated by changing the version numbers below to
17 | # the latest version available on pub.dev. To see which dependencies have newer
18 | # versions available, run `flutter pub outdated`.
19 | dependencies:
20 | flutter:
21 | sdk: flutter
22 |
23 | signalr_flutter:
24 | # When depending on this package from a real application you should use:
25 | # signalr_flutter: ^x.y.z
26 | # See https://dart.dev/tools/pub/dependencies#version-constraints
27 | # The example app is bundled with the plugin so we use a path dependency on
28 | # the parent directory to use the current plugin's version.
29 | path: ../
30 |
31 | # The following adds the Cupertino Icons font to your application.
32 | # Use with the CupertinoIcons class for iOS style icons.
33 | cupertino_icons: ^1.0.5
34 |
35 | dev_dependencies:
36 | flutter_test:
37 | sdk: flutter
38 |
39 | # The "flutter_lints" package below contains a set of recommended lints to
40 | # encourage good coding practices. The lint set provided by the package is
41 | # activated in the `analysis_options.yaml` file located at the root of your
42 | # package. See that file for information about deactivating specific lint
43 | # rules and activating additional ones.
44 | flutter_lints: ^2.0.1
45 |
46 | # For information on the generic Dart part of this file, see the
47 | # following page: https://dart.dev/tools/pub/pubspec
48 |
49 | # The following section is specific to Flutter.
50 | flutter:
51 |
52 | uses-material-design: true
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
13 |
17 |
21 |
26 |
30 |
31 |
32 |
33 |
34 |
35 |
37 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 0.0.1
2 |
3 | * Initial release.
4 |
5 | ## 0.0.2
6 |
7 | * Minor Updates.
8 |
9 | ## 0.0.3
10 |
11 | * Connection Headers and Transport customization added
12 | * Minor changes and a bug fix for invokeServerMethod
13 |
14 | ## 0.0.4
15 |
16 | * Minor Updates.
17 |
18 | ## 0.0.5
19 |
20 | * Fixed a bug where invokeMethod only accepting string as return value
21 |
22 | ## 0.0.6-dev.1
23 |
24 | * Possible fix for callbacks throwing exception about type mismatch.
25 | * invokeMethod now has generic return type & upto 10 arguments support.
26 |
27 | ## 0.0.6-dev.2
28 |
29 | * HubCallBack function now returns the value as well as the subscribed method name.
30 | * invokeMethod now can take as many arguments as you want.
31 |
32 | ## 0.0.6-dev.3
33 |
34 | * Possible fix for ios Hub events not returning
35 |
36 | ## 0.1.0-dev.1
37 |
38 | * Fix for ios Hub events not returning
39 |
40 | ## 0.1.0-dev.2
41 |
42 | * Fixed Duplicated Hub events for ios.
43 |
44 | ## 0.1.0
45 |
46 | * Fix a issue where hub callback only accepting strings.
47 | * Hub callback now returns the message as well as the subscribed method name.
48 | * Made invokeMethod generic.
49 | * As many arguments as you want in invokeMethod.
50 | * fix for ios Hub events not working.
51 |
52 | ## 0.1.1
53 |
54 | * Null Safety Support
55 |
56 | ## 0.1.2
57 |
58 | * IsConnected Method Added
59 |
60 | ## 0.2.0-dev.1
61 |
62 | * Rewrote the plugin using pigeon
63 | * **Breaking Changes**:
64 | * `invokeMethod` now take only strings as arguments instead of dynamic.
65 | * `invokeMethod` now returns only string as result.
66 | * `hubCallback` now also returns string as message instead of dynamic.
67 |
68 | ## 0.2.0-dev.2
69 |
70 | * Fix for invokeMethod calls having no return value.
71 |
72 | ## 0.2.0-dev.3
73 |
74 | * Updated signalr for iOS.
75 | * Transport fallback properly added for iOS.
76 |
77 | ## 0.2.0-dev.4
78 |
79 | * App bundle build issue fix.
80 |
81 | ## 0.2.0-dev.5
82 |
83 | * Removed unnecessary platform exceptions.
84 | * Updated dependencies.
85 |
86 | ## 0.2.0
87 |
88 | * Rewrote the plugin using pigeon.
89 | * Removed unnecessary platform exceptions.
90 | * Updated signalr for iOS.
91 | * Updated all dependencies to the latest.
92 | * **Breaking Changes**:
93 | * `invokeMethod` now take only strings as arguments instead of dynamic.
94 | * `invokeMethod` now returns only string as result.
95 | * `hubCallback` now also returns string as message instead of dynamic.
96 |
97 | ## 0.2.1
98 |
99 | * [#64] upgraded GPA (Android Gradle Plugin) to version 8 to comply to deprication of the old flutter gradle implementation.
100 |
101 | * [#64] Plugin now requires the following:
102 | - Flutter >=3.19.0
103 | - Dart >=3.3.0
104 | - compileSDK 33 for Android part
105 | - Java 17 for Android part
106 | - Gradle 8.0 for Android part
107 |
108 | * Connection error feedback with `connectionErrorCallback`
109 |
110 |
111 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/example/lib/main.dart:
--------------------------------------------------------------------------------
1 | // ignore_for_file: avoid_print
2 |
3 | import 'package:flutter/material.dart';
4 | import 'dart:async';
5 |
6 | import 'package:signalr_flutter/signalr_api.dart';
7 | import 'package:signalr_flutter/signalr_flutter.dart';
8 |
9 | void main() {
10 | runApp(const MyApp());
11 | }
12 |
13 | class MyApp extends StatefulWidget {
14 | const MyApp({Key? key}) : super(key: key);
15 |
16 | @override
17 | State createState() => _MyAppState();
18 | }
19 |
20 | class _MyAppState extends State {
21 | String signalRStatus = "disconnected";
22 | late SignalR signalR;
23 |
24 | @override
25 | void initState() {
26 | super.initState();
27 | initPlatformState();
28 | }
29 |
30 | // Platform messages are asynchronous, so we initialize in an async method.
31 | Future initPlatformState() async {
32 | signalR = SignalR(
33 | "",
34 | "",
35 | hubMethods: [""],
36 | statusChangeCallback: _onStatusChange,
37 | hubCallback: _onNewMessage,
38 | );
39 | }
40 |
41 | @override
42 | Widget build(BuildContext context) {
43 | return MaterialApp(
44 | home: Scaffold(
45 | appBar: AppBar(
46 | title: const Text("SignalR Plugin Example App"),
47 | ),
48 | body: Column(
49 | crossAxisAlignment: CrossAxisAlignment.stretch,
50 | mainAxisAlignment: MainAxisAlignment.center,
51 | children: [
52 | Text(
53 | "Connection Status: $signalRStatus\n",
54 | style: Theme.of(context).textTheme.titleLarge,
55 | textAlign: TextAlign.center,
56 | ),
57 | Padding(
58 | padding: const EdgeInsets.only(top: 20.0),
59 | child: ElevatedButton(
60 | onPressed: _buttonTapped,
61 | child: const Text("Invoke Method"),
62 | ),
63 | )
64 | ],
65 | ),
66 | floatingActionButton: FloatingActionButton(
67 | child: const Icon(Icons.cast_connected),
68 | onPressed: () async {
69 | final isConnected = await signalR.isConnected();
70 | if (!isConnected) {
71 | final connId = await signalR.connect();
72 | print("Connection ID: $connId");
73 | } else {
74 | signalR.stop();
75 | }
76 | },
77 | ),
78 | ),
79 | );
80 | }
81 |
82 | void _onStatusChange(ConnectionStatus? status) {
83 | if (mounted) {
84 | setState(() {
85 | signalRStatus = status?.name ?? ConnectionStatus.disconnected.name;
86 | });
87 | }
88 | }
89 |
90 | void _onNewMessage(String methodName, String message) {
91 | print("MethodName = $methodName, Message = $message");
92 | }
93 |
94 | void _buttonTapped() async {
95 | try {
96 | final result = await signalR.invokeMethod(
97 | "",
98 | arguments: [""],
99 | );
100 | print(result);
101 | } catch (e) {
102 | print(e);
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/ios/Assets/SwiftR.js:
--------------------------------------------------------------------------------
1 | window.swiftR = {
2 | connection: null,
3 | hubs: {},
4 | transport: ['webSockets','serverSentEvents','longPolling'],
5 | headers: {},
6 | messages: {}
7 | };
8 |
9 | $(function () {
10 | $.ajaxSetup({
11 | beforeSend: function (jqxhr) {
12 | for (var h in swiftR.headers) {
13 | jqxhr.setRequestHeader(h, swiftR.headers[h]);
14 | }
15 | }
16 | });
17 | postMessage({ message: 'ready' });
18 | });
19 |
20 | function initialize(baseUrl, isHub) {
21 | swiftR.connection = isHub ? $.hubConnection(baseUrl) : $.connection(baseUrl);
22 | var connection = swiftR.connection;
23 |
24 | connection.logging = true;
25 |
26 | if (!isHub) {
27 | connection.received(function (data) {
28 | postMessage({ data: data });
29 | });
30 | }
31 |
32 | connection.starting(function () {
33 | postMessage({ message: 'starting' });
34 | });
35 |
36 | connection.connectionSlow(function () {
37 | postMessage({ message: 'connectionSlow' });
38 | });
39 |
40 | connection.reconnecting(function () {
41 | postMessage({ message: 'reconnecting' });
42 | });
43 |
44 | connection.reconnected(function () {
45 | postMessage({ message: 'reconnected' });
46 | });
47 |
48 | connection.disconnected(function () {
49 | postMessage({ message: 'disconnected' });
50 | });
51 |
52 | connection.error(function (error) {
53 | postMessage({ message: 'error', error: processError(error) });
54 | });
55 | }
56 |
57 | function start() {
58 | swiftR.connection.start({ transport: swiftR.transport }).done(function () {
59 | postMessage({ message: 'connected', connectionId: swiftR.connection.id });
60 | }).fail(function () {
61 | postMessage({ message: 'connectionFailed' });
62 | });
63 | }
64 |
65 | function addHandler(id, hubName, method) {
66 | var hub = ensureHub(hubName);
67 |
68 | hub.on(method, function () {
69 | postMessage({
70 | id: id,
71 | hub: hub.hubName,
72 | method: method,
73 | arguments: [].slice.call(arguments)
74 | });
75 | });
76 | }
77 |
78 | function postMessage(msg) {
79 | var id = Math.random().toString(36).slice(2, 10);
80 | swiftR.messages[id] = msg;
81 |
82 | if (window.webkit) {
83 | webkit.messageHandlers.interOp.postMessage(id);
84 | } else {
85 | var frame = $('', { src: 'swiftr://' + id });
86 | $('body').append(frame);
87 | frame.remove();
88 | }
89 | }
90 |
91 | function ensureHub(name) {
92 | var hub = swiftR.hubs[name];
93 |
94 | if (!hub) {
95 | hub = swiftR.connection.createHubProxy(name);
96 | swiftR.hubs[name] = hub;
97 | }
98 |
99 | return hub;
100 | }
101 |
102 | function processError(error) {
103 | var err = {
104 | message: error.message || 'An unknown error has occurred.'
105 | }
106 |
107 | if (typeof error.source === 'string') {
108 | err.source = error.source;
109 | }
110 |
111 | return err;
112 | }
113 |
114 | function readMessage(id) {
115 | var msg = swiftR.messages[id];
116 | delete swiftR.messages[id];
117 | return window.webkit ? msg : JSON.stringify(msg);
118 | }
119 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
52 |
54 |
60 |
61 |
62 |
63 |
69 |
71 |
77 |
78 |
79 |
80 |
82 |
83 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/ios/Classes/SignalrApi.h:
--------------------------------------------------------------------------------
1 | // Autogenerated from Pigeon (v4.2.5), do not edit directly.
2 | // See also: https://pub.dev/packages/pigeon
3 | #import
4 | @protocol FlutterBinaryMessenger;
5 | @protocol FlutterMessageCodec;
6 | @class FlutterError;
7 | @class FlutterStandardTypedData;
8 |
9 | NS_ASSUME_NONNULL_BEGIN
10 |
11 | /// Transport method of the signalr connection.
12 | typedef NS_ENUM(NSUInteger, FLTTransport) {
13 | FLTTransportAuto = 0,
14 | FLTTransportServerSentEvents = 1,
15 | FLTTransportLongPolling = 2,
16 | };
17 |
18 | /// SignalR connection status
19 | typedef NS_ENUM(NSUInteger, FLTConnectionStatus) {
20 | FLTConnectionStatusConnecting = 0,
21 | FLTConnectionStatusConnected = 1,
22 | FLTConnectionStatusReconnecting = 2,
23 | FLTConnectionStatusDisconnected = 3,
24 | FLTConnectionStatusConnectionSlow = 4,
25 | FLTConnectionStatusConnectionError = 5,
26 | };
27 |
28 | @class FLTConnectionOptions;
29 | @class FLTStatusChangeResult;
30 |
31 | @interface FLTConnectionOptions : NSObject
32 | + (instancetype)makeWithBaseUrl:(nullable NSString *)baseUrl
33 | hubName:(nullable NSString *)hubName
34 | queryString:(nullable NSString *)queryString
35 | hubMethods:(nullable NSArray *)hubMethods
36 | headers:(nullable NSDictionary *)headers
37 | transport:(FLTTransport)transport;
38 | @property(nonatomic, copy, nullable) NSString * baseUrl;
39 | @property(nonatomic, copy, nullable) NSString * hubName;
40 | @property(nonatomic, copy, nullable) NSString * queryString;
41 | @property(nonatomic, strong, nullable) NSArray * hubMethods;
42 | @property(nonatomic, strong, nullable) NSDictionary * headers;
43 | @property(nonatomic, assign) FLTTransport transport;
44 | @end
45 |
46 | @interface FLTStatusChangeResult : NSObject
47 | + (instancetype)makeWithConnectionId:(nullable NSString *)connectionId
48 | status:(FLTConnectionStatus)status
49 | errorMessage:(nullable NSString *)errorMessage;
50 | @property(nonatomic, copy, nullable) NSString * connectionId;
51 | @property(nonatomic, assign) FLTConnectionStatus status;
52 | @property(nonatomic, copy, nullable) NSString * errorMessage;
53 | @end
54 |
55 | /// The codec used by FLTSignalRHostApi.
56 | NSObject *FLTSignalRHostApiGetCodec(void);
57 |
58 | @protocol FLTSignalRHostApi
59 | - (void)connectConnectionOptions:(FLTConnectionOptions *)connectionOptions completion:(void(^)(NSString *_Nullable, FlutterError *_Nullable))completion;
60 | - (void)reconnectWithCompletion:(void(^)(NSString *_Nullable, FlutterError *_Nullable))completion;
61 | - (void)stopWithCompletion:(void(^)(FlutterError *_Nullable))completion;
62 | - (void)isConnectedWithCompletion:(void(^)(NSNumber *_Nullable, FlutterError *_Nullable))completion;
63 | - (void)invokeMethodMethodName:(NSString *)methodName arguments:(NSArray *)arguments completion:(void(^)(NSString *_Nullable, FlutterError *_Nullable))completion;
64 | @end
65 |
66 | extern void FLTSignalRHostApiSetup(id binaryMessenger, NSObject *_Nullable api);
67 |
68 | /// The codec used by FLTSignalRPlatformApi.
69 | NSObject *FLTSignalRPlatformApiGetCodec(void);
70 |
71 | @interface FLTSignalRPlatformApi : NSObject
72 | - (instancetype)initWithBinaryMessenger:(id)binaryMessenger;
73 | - (void)onStatusChangeStatusChangeResult:(FLTStatusChangeResult *)statusChangeResult completion:(void(^)(NSError *_Nullable))completion;
74 | - (void)onNewMessageHubName:(NSString *)hubName message:(NSString *)message completion:(void(^)(NSError *_Nullable))completion;
75 | @end
76 | NS_ASSUME_NONNULL_END
77 |
--------------------------------------------------------------------------------
/lib/signalr_flutter.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:flutter/foundation.dart';
4 | import 'package:signalr_flutter/signalr_api.dart';
5 | import 'package:signalr_flutter/signalr_platform_interface.dart';
6 |
7 | class SignalR extends SignalrPlatformInterface implements SignalRPlatformApi {
8 | // Private variables
9 | static final SignalRHostApi _signalrApi = SignalRHostApi();
10 | final Function(String?)? connectionErrorCallback;
11 | // Constructor
12 | SignalR(
13 | super.baseUrl,
14 | super.hubName, {
15 | super.queryString,
16 | super.headers,
17 | super.hubMethods,
18 | Transport transport = Transport.auto,
19 | super.statusChangeCallback,
20 | super.hubCallback,
21 | this.connectionErrorCallback,
22 | });
23 |
24 | //---- Callback Methods ----//
25 | // ------------------------//
26 | @override
27 | Future onNewMessage(String hubName, String message) async {
28 | hubCallback?.call(hubName, message);
29 | }
30 |
31 | @override
32 | Future onStatusChange(StatusChangeResult statusChangeResult) async {
33 | connectionId = statusChangeResult.connectionId;
34 |
35 | statusChangeCallback?.call(statusChangeResult.status);
36 |
37 | if (statusChangeResult.errorMessage != null) {
38 | debugPrint('SignalR Error: ${statusChangeResult.errorMessage}');
39 | connectionErrorCallback?.call(statusChangeResult.errorMessage);
40 | }
41 | }
42 |
43 | //---- Public Methods ----//
44 | // ------------------------//
45 |
46 | /// Connect to the SignalR Server with given [baseUrl] & [hubName].
47 | ///
48 | /// [queryString] is a optional field to send query to server.
49 | ///
50 | /// Returns the [connectionId].
51 | @override
52 | Future connect() async {
53 | try {
54 | // Construct ConnectionOptions
55 | ConnectionOptions options = ConnectionOptions(
56 | baseUrl: baseUrl,
57 | hubName: hubName,
58 | queryString: queryString,
59 | hubMethods: hubMethods,
60 | headers: headers,
61 | transport: transport,
62 | );
63 |
64 | // Register SignalR Callbacks
65 | SignalRPlatformApi.setup(this);
66 |
67 | connectionId = await _signalrApi.connect(options);
68 |
69 | return connectionId;
70 | } catch (e) {
71 | return Future.error(e);
72 | }
73 | }
74 |
75 | /// Try to Reconnect SignalR connection if it gets disconnected.
76 | ///
77 | /// Returns the [connectionId]
78 | @override
79 | Future reconnect() async {
80 | try {
81 | connectionId = await _signalrApi.reconnect();
82 | return connectionId;
83 | } catch (e) {
84 | return Future.error(e);
85 | }
86 | }
87 |
88 | /// Stops SignalR connection
89 | @override
90 | Future stop() async {
91 | try {
92 | await _signalrApi.stop();
93 | } catch (e) {
94 | return Future.error(e);
95 | }
96 | }
97 |
98 | /// Checks if SignalR connection is still active.
99 | ///
100 | /// Returns a boolean value
101 | @override
102 | Future isConnected() async {
103 | try {
104 | return await _signalrApi.isConnected();
105 | } catch (e) {
106 | return Future.error(e);
107 | }
108 | }
109 |
110 | /// Invoke any server method with optional [arguments].
111 | @override
112 | Future invokeMethod(String methodName, {List? arguments}) async {
113 | try {
114 | return await _signalrApi.invokeMethod(methodName, arguments ?? List.empty());
115 | } catch (e) {
116 | return Future.error(e);
117 | }
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/example/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | async:
5 | dependency: transitive
6 | description:
7 | name: async
8 | sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
9 | url: "https://pub.dev"
10 | source: hosted
11 | version: "2.13.0"
12 | boolean_selector:
13 | dependency: transitive
14 | description:
15 | name: boolean_selector
16 | sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
17 | url: "https://pub.dev"
18 | source: hosted
19 | version: "2.1.2"
20 | characters:
21 | dependency: transitive
22 | description:
23 | name: characters
24 | sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
25 | url: "https://pub.dev"
26 | source: hosted
27 | version: "1.4.0"
28 | clock:
29 | dependency: transitive
30 | description:
31 | name: clock
32 | sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
33 | url: "https://pub.dev"
34 | source: hosted
35 | version: "1.1.2"
36 | collection:
37 | dependency: transitive
38 | description:
39 | name: collection
40 | sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
41 | url: "https://pub.dev"
42 | source: hosted
43 | version: "1.19.1"
44 | cupertino_icons:
45 | dependency: "direct main"
46 | description:
47 | name: cupertino_icons
48 | sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be
49 | url: "https://pub.dev"
50 | source: hosted
51 | version: "1.0.5"
52 | fake_async:
53 | dependency: transitive
54 | description:
55 | name: fake_async
56 | sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
57 | url: "https://pub.dev"
58 | source: hosted
59 | version: "1.3.3"
60 | flutter:
61 | dependency: "direct main"
62 | description: flutter
63 | source: sdk
64 | version: "0.0.0"
65 | flutter_lints:
66 | dependency: "direct dev"
67 | description:
68 | name: flutter_lints
69 | sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
70 | url: "https://pub.dev"
71 | source: hosted
72 | version: "2.0.1"
73 | flutter_test:
74 | dependency: "direct dev"
75 | description: flutter
76 | source: sdk
77 | version: "0.0.0"
78 | leak_tracker:
79 | dependency: transitive
80 | description:
81 | name: leak_tracker
82 | sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0"
83 | url: "https://pub.dev"
84 | source: hosted
85 | version: "10.0.9"
86 | leak_tracker_flutter_testing:
87 | dependency: transitive
88 | description:
89 | name: leak_tracker_flutter_testing
90 | sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
91 | url: "https://pub.dev"
92 | source: hosted
93 | version: "3.0.9"
94 | leak_tracker_testing:
95 | dependency: transitive
96 | description:
97 | name: leak_tracker_testing
98 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
99 | url: "https://pub.dev"
100 | source: hosted
101 | version: "3.0.1"
102 | lints:
103 | dependency: transitive
104 | description:
105 | name: lints
106 | sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593"
107 | url: "https://pub.dev"
108 | source: hosted
109 | version: "2.0.1"
110 | matcher:
111 | dependency: transitive
112 | description:
113 | name: matcher
114 | sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
115 | url: "https://pub.dev"
116 | source: hosted
117 | version: "0.12.17"
118 | material_color_utilities:
119 | dependency: transitive
120 | description:
121 | name: material_color_utilities
122 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
123 | url: "https://pub.dev"
124 | source: hosted
125 | version: "0.11.1"
126 | meta:
127 | dependency: transitive
128 | description:
129 | name: meta
130 | sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
131 | url: "https://pub.dev"
132 | source: hosted
133 | version: "1.16.0"
134 | path:
135 | dependency: transitive
136 | description:
137 | name: path
138 | sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
139 | url: "https://pub.dev"
140 | source: hosted
141 | version: "1.9.1"
142 | signalr_flutter:
143 | dependency: "direct main"
144 | description:
145 | path: ".."
146 | relative: true
147 | source: path
148 | version: "0.2.0"
149 | sky_engine:
150 | dependency: transitive
151 | description: flutter
152 | source: sdk
153 | version: "0.0.0"
154 | source_span:
155 | dependency: transitive
156 | description:
157 | name: source_span
158 | sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
159 | url: "https://pub.dev"
160 | source: hosted
161 | version: "1.10.1"
162 | stack_trace:
163 | dependency: transitive
164 | description:
165 | name: stack_trace
166 | sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
167 | url: "https://pub.dev"
168 | source: hosted
169 | version: "1.12.1"
170 | stream_channel:
171 | dependency: transitive
172 | description:
173 | name: stream_channel
174 | sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
175 | url: "https://pub.dev"
176 | source: hosted
177 | version: "2.1.4"
178 | string_scanner:
179 | dependency: transitive
180 | description:
181 | name: string_scanner
182 | sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
183 | url: "https://pub.dev"
184 | source: hosted
185 | version: "1.4.1"
186 | term_glyph:
187 | dependency: transitive
188 | description:
189 | name: term_glyph
190 | sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
191 | url: "https://pub.dev"
192 | source: hosted
193 | version: "1.2.2"
194 | test_api:
195 | dependency: transitive
196 | description:
197 | name: test_api
198 | sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
199 | url: "https://pub.dev"
200 | source: hosted
201 | version: "0.7.4"
202 | vector_math:
203 | dependency: transitive
204 | description:
205 | name: vector_math
206 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
207 | url: "https://pub.dev"
208 | source: hosted
209 | version: "2.1.4"
210 | vm_service:
211 | dependency: transitive
212 | description:
213 | name: vm_service
214 | sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02
215 | url: "https://pub.dev"
216 | source: hosted
217 | version: "15.0.0"
218 | sdks:
219 | dart: ">=3.7.0-0 <4.0.0"
220 | flutter: ">=3.19.0"
221 |
--------------------------------------------------------------------------------
/ios/Classes/SwiftSignalrFlutterPlugin.swift:
--------------------------------------------------------------------------------
1 | import Flutter
2 | import UIKit
3 |
4 | public class SwiftSignalrFlutterPlugin: NSObject, FlutterPlugin, FLTSignalRHostApi {
5 | private static var signalrApi : FLTSignalRPlatformApi?
6 |
7 | private var hub: Hub!
8 | private var connection: SignalR!
9 |
10 | public static func register(with registrar: FlutterPluginRegistrar) {
11 | let messenger : FlutterBinaryMessenger = registrar.messenger()
12 | let api : FLTSignalRHostApi & NSObjectProtocol = SwiftSignalrFlutterPlugin.init()
13 | FLTSignalRHostApiSetup(messenger, api)
14 | signalrApi = FLTSignalRPlatformApi.init(binaryMessenger: messenger)
15 | }
16 |
17 | public func detachFromEngine(for registrar: FlutterPluginRegistrar) {
18 | let messenger : FlutterBinaryMessenger = registrar.messenger()
19 | FLTSignalRHostApiSetup(messenger, nil)
20 | SwiftSignalrFlutterPlugin.signalrApi = nil
21 | }
22 |
23 | public func connect(_ connectionOptions: FLTConnectionOptions, completion: @escaping (String?, FlutterError?) -> Void) {
24 | connection = SignalR(connectionOptions.baseUrl ?? "")
25 |
26 | if let queryString = connectionOptions.queryString, !queryString.isEmpty {
27 | let qs = queryString.components(separatedBy: "=")
28 | connection.queryString = [qs[0]:qs[1]]
29 | }
30 |
31 | switch connectionOptions.transport {
32 | case .longPolling:
33 | connection.transport = Transport.longPolling
34 | case .serverSentEvents:
35 | connection.transport = Transport.serverSentEvents
36 | case .auto:
37 | connection.transport = Transport.auto
38 | @unknown default:
39 | break
40 | }
41 |
42 | if let headers = connectionOptions.headers, !headers.isEmpty {
43 | connection.headers = headers
44 | }
45 |
46 | if let hubName = connectionOptions.hubName {
47 | hub = connection.createHubProxy(hubName)
48 | }
49 |
50 | if let hubMethods = connectionOptions.hubMethods, !hubMethods.isEmpty {
51 | hubMethods.forEach { (methodName) in
52 | hub.on(methodName) { (args) in
53 | SwiftSignalrFlutterPlugin.signalrApi?.onNewMessageHubName(methodName, message: args?[0] as? String ?? "", completion: { error in })
54 | }
55 | }
56 | }
57 |
58 | connection.starting = {
59 | let statusChangeResult : FLTStatusChangeResult = FLTStatusChangeResult.init()
60 | statusChangeResult.connectionId = nil
61 | statusChangeResult.status = FLTConnectionStatus.connecting
62 | SwiftSignalrFlutterPlugin.signalrApi?.onStatusChange(statusChangeResult, completion: { error in })
63 | }
64 |
65 | connection.reconnecting = {
66 | let statusChangeResult : FLTStatusChangeResult = FLTStatusChangeResult.init()
67 | statusChangeResult.connectionId = nil
68 | statusChangeResult.status = FLTConnectionStatus.reconnecting
69 | SwiftSignalrFlutterPlugin.signalrApi?.onStatusChange(statusChangeResult, completion: { error in })
70 | }
71 |
72 | connection.connected = { [weak self] in
73 | let statusChangeResult : FLTStatusChangeResult = FLTStatusChangeResult.init()
74 | statusChangeResult.connectionId = self?.connection.connectionID
75 | statusChangeResult.status = FLTConnectionStatus.connected
76 | SwiftSignalrFlutterPlugin.signalrApi?.onStatusChange(statusChangeResult, completion: { error in })
77 | }
78 |
79 | connection.reconnected = { [weak self] in
80 | let statusChangeResult : FLTStatusChangeResult = FLTStatusChangeResult.init()
81 | statusChangeResult.connectionId = self?.connection.connectionID
82 | statusChangeResult.status = FLTConnectionStatus.connected
83 | SwiftSignalrFlutterPlugin.signalrApi?.onStatusChange(statusChangeResult, completion: { error in })
84 | }
85 |
86 | connection.disconnected = { [weak self] in
87 | let statusChangeResult : FLTStatusChangeResult = FLTStatusChangeResult.init()
88 | statusChangeResult.connectionId = self?.connection.connectionID
89 | statusChangeResult.status = FLTConnectionStatus.disconnected
90 | SwiftSignalrFlutterPlugin.signalrApi?.onStatusChange(statusChangeResult, completion: { error in })
91 | }
92 |
93 | connection.connectionSlow = { [weak self] in
94 | print("Connection slow...")
95 | let statusChangeResult : FLTStatusChangeResult = FLTStatusChangeResult.init()
96 | statusChangeResult.connectionId = self?.connection.connectionID
97 | statusChangeResult.status = FLTConnectionStatus.connectionSlow
98 | SwiftSignalrFlutterPlugin.signalrApi?.onStatusChange(statusChangeResult, completion: { error in })
99 | }
100 |
101 | connection.error = { error in
102 | print("SignalR Error: \(error ?? [:])")
103 | let statusChangeResult : FLTStatusChangeResult = FLTStatusChangeResult.init()
104 | statusChangeResult.connectionId = nil
105 | statusChangeResult.status = FLTConnectionStatus.connectionError
106 | statusChangeResult.errorMessage = error?.description
107 | SwiftSignalrFlutterPlugin.signalrApi?.onStatusChange(statusChangeResult, completion: { error in })
108 | }
109 |
110 | connection.start()
111 | completion(self.connection.connectionID ?? "", nil)
112 | }
113 |
114 | public func reconnect(completion: @escaping (String?, FlutterError?) -> Void) {
115 | if let connection = self.connection {
116 | connection.start()
117 | completion(self.connection.connectionID ?? "", nil)
118 | } else {
119 | completion(nil, FlutterError(code: "platform-error", message: "SignalR Connection not found or null", details: "Start SignalR connection first"))
120 | }
121 | }
122 |
123 | public func stop(completion: @escaping (FlutterError?) -> Void) {
124 | if let connection = self.connection {
125 | connection.stop()
126 | } else {
127 | completion(FlutterError(code: "platform-error", message: "SignalR Connection not found or null", details: "Start SignalR connection first"))
128 | }
129 | }
130 |
131 | public func isConnected(completion: @escaping (NSNumber?, FlutterError?) -> Void) {
132 | if let connection = self.connection {
133 | switch connection.state {
134 | case .connected:
135 | completion(true, nil)
136 | default:
137 | completion(false, nil)
138 | }
139 | } else {
140 | completion(false, nil)
141 | }
142 | }
143 |
144 | public func invokeMethodMethodName(_ methodName: String, arguments: [String], completion: @escaping (String?, FlutterError?) -> Void) {
145 | do {
146 | if let hub = self.hub {
147 | try hub.invoke(methodName, arguments: arguments, callback: { (res, error) in
148 | if let error = error {
149 | completion(nil, FlutterError(code: "platform-error", message: String(describing: error), details: nil))
150 | } else {
151 | completion(res as? String ?? "", nil)
152 | }
153 | })
154 | } else {
155 | throw NSError.init(domain: "NullPointerException", code: 0, userInfo: [NSLocalizedDescriptionKey : "Hub is null. Initiate a connection first."])
156 | }
157 | } catch {
158 | completion(nil ,FlutterError.init(code: "platform-error", message: error.localizedDescription, details: nil))
159 | }
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/android/src/main/kotlin/dev/asdevs/signalr_flutter/SignalRFlutterPlugin.kt:
--------------------------------------------------------------------------------
1 | package dev.asdevs.signalr_flutter
2 |
3 | import android.os.Handler
4 | import android.os.Looper
5 |
6 | import io.flutter.embedding.engine.plugins.FlutterPlugin
7 | import microsoft.aspnet.signalr.client.ConnectionState
8 | import microsoft.aspnet.signalr.client.Credentials
9 | import microsoft.aspnet.signalr.client.LogLevel
10 | import microsoft.aspnet.signalr.client.SignalRFuture
11 | import microsoft.aspnet.signalr.client.hubs.HubConnection
12 | import microsoft.aspnet.signalr.client.hubs.HubProxy
13 | import microsoft.aspnet.signalr.client.transport.LongPollingTransport
14 | import microsoft.aspnet.signalr.client.transport.ServerSentEventsTransport
15 | import java.lang.Exception
16 |
17 | /** SignalrFlutterPlugin */
18 | class SignalrFlutterPlugin : FlutterPlugin, SignalrApi.SignalRHostApi {
19 | private lateinit var connection: HubConnection
20 | private lateinit var hub: HubProxy
21 |
22 | private lateinit var signalrApi: SignalrApi.SignalRPlatformApi
23 |
24 | override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
25 | SignalrApi.SignalRHostApi.setup(flutterPluginBinding.binaryMessenger, this)
26 | signalrApi = SignalrApi.SignalRPlatformApi(flutterPluginBinding.binaryMessenger)
27 | }
28 |
29 | override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
30 | SignalrApi.SignalRHostApi.setup(binding.binaryMessenger, null)
31 | }
32 |
33 | override fun connect(
34 | connectionOptions: SignalrApi.ConnectionOptions,
35 | result: SignalrApi.Result?
36 | ) {
37 | try {
38 | connection =
39 | if (connectionOptions.queryString?.isNotEmpty() == true) {
40 | HubConnection(
41 | connectionOptions.baseUrl,
42 | connectionOptions.queryString,
43 | true
44 | ) { _: String, _: LogLevel ->
45 | }
46 | } else {
47 | HubConnection(connectionOptions.baseUrl)
48 | }
49 |
50 | if (connectionOptions.headers?.isNotEmpty() == true) {
51 | val cred = Credentials { request ->
52 | request.headers = connectionOptions.headers
53 | }
54 | connection.credentials = cred
55 | }
56 |
57 | hub = connection.createHubProxy(connectionOptions.hubName)
58 |
59 | connectionOptions.hubMethods?.forEach { methodName ->
60 | hub.on(methodName, { res ->
61 | Handler(Looper.getMainLooper()).post {
62 | signalrApi.onNewMessage(methodName, res) { }
63 | }
64 | }, String::class.java)
65 | }
66 |
67 | connection.connected {
68 | Handler(Looper.getMainLooper()).post {
69 | val statusChangeResult = SignalrApi.StatusChangeResult()
70 | statusChangeResult.connectionId = connection.connectionId
71 | statusChangeResult.status = SignalrApi.ConnectionStatus.CONNECTED
72 | signalrApi.onStatusChange(statusChangeResult) { }
73 | }
74 | }
75 |
76 | connection.reconnected {
77 | Handler(Looper.getMainLooper()).post {
78 | val statusChangeResult = SignalrApi.StatusChangeResult()
79 | statusChangeResult.connectionId = connection.connectionId
80 | statusChangeResult.status = SignalrApi.ConnectionStatus.CONNECTED
81 | signalrApi.onStatusChange(statusChangeResult) { }
82 | }
83 | }
84 |
85 | connection.reconnecting {
86 | Handler(Looper.getMainLooper()).post {
87 | val statusChangeResult = SignalrApi.StatusChangeResult()
88 | statusChangeResult.connectionId = connection.connectionId
89 | statusChangeResult.status = SignalrApi.ConnectionStatus.RECONNECTING
90 | signalrApi.onStatusChange(statusChangeResult) { }
91 | }
92 | }
93 |
94 | connection.closed {
95 | Handler(Looper.getMainLooper()).post {
96 | val statusChangeResult = SignalrApi.StatusChangeResult()
97 | statusChangeResult.connectionId = connection.connectionId
98 | statusChangeResult.status = SignalrApi.ConnectionStatus.DISCONNECTED
99 | signalrApi.onStatusChange(statusChangeResult) { }
100 | }
101 | }
102 |
103 | connection.connectionSlow {
104 | Handler(Looper.getMainLooper()).post {
105 | val statusChangeResult = SignalrApi.StatusChangeResult()
106 | statusChangeResult.connectionId = connection.connectionId
107 | statusChangeResult.status = SignalrApi.ConnectionStatus.CONNECTION_SLOW
108 | signalrApi.onStatusChange(statusChangeResult) { }
109 | }
110 | }
111 |
112 | connection.error { handler ->
113 | Handler(Looper.getMainLooper()).post {
114 | val statusChangeResult = SignalrApi.StatusChangeResult()
115 | statusChangeResult.status = SignalrApi.ConnectionStatus.CONNECTION_ERROR
116 | statusChangeResult.errorMessage = handler.localizedMessage
117 | signalrApi.onStatusChange(statusChangeResult) { }
118 | }
119 | }
120 |
121 | when (connectionOptions.transport) {
122 | SignalrApi.Transport.SERVER_SENT_EVENTS -> connection.start(
123 | ServerSentEventsTransport(
124 | connection.logger
125 | )
126 | )
127 | SignalrApi.Transport.LONG_POLLING -> connection.start(
128 | LongPollingTransport(
129 | connection.logger
130 | )
131 | )
132 | else -> {
133 | connection.start()
134 | }
135 | }
136 |
137 | result?.success(connection.connectionId ?: "")
138 | } catch (ex: Exception) {
139 | result?.error(ex)
140 | }
141 | }
142 |
143 | override fun reconnect(result: SignalrApi.Result?) {
144 | try {
145 | connection.start()
146 | result?.success(connection.connectionId ?: "")
147 | } catch (ex: Exception) {
148 | result?.error(ex)
149 | }
150 | }
151 |
152 | override fun stop(result: SignalrApi.Result?) {
153 | try {
154 | connection.stop()
155 | } catch (ex: Exception) {
156 | result?.error(ex)
157 | }
158 | }
159 |
160 | override fun isConnected(result: SignalrApi.Result?) {
161 | try {
162 | if (this::connection.isInitialized) {
163 | when (connection.state) {
164 | ConnectionState.Connected -> result?.success(true)
165 | else -> result?.success(false)
166 | }
167 | } else {
168 | result?.success(false)
169 | }
170 | } catch (ex: Exception) {
171 | result?.error(ex)
172 | }
173 | }
174 |
175 | override fun invokeMethod(
176 | methodName: String,
177 | arguments: MutableList,
178 | result: SignalrApi.Result?
179 | ) {
180 | try {
181 | val res: SignalRFuture =
182 | hub.invoke(String::class.java, methodName, *arguments.toTypedArray())
183 |
184 | res.done { msg: String? ->
185 | Handler(Looper.getMainLooper()).post {
186 | result?.success(msg ?: "")
187 | }
188 | }
189 |
190 | res.onError { throwable ->
191 | throw throwable
192 | }
193 | } catch (ex: Exception) {
194 | result?.error(ex)
195 | }
196 | }
197 | }
198 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | _fe_analyzer_shared:
5 | dependency: transitive
6 | description:
7 | name: _fe_analyzer_shared
8 | sha256: "4897882604d919befd350648c7f91926a9d5de99e67b455bf0917cc2362f4bb8"
9 | url: "https://pub.dev"
10 | source: hosted
11 | version: "47.0.0"
12 | analyzer:
13 | dependency: transitive
14 | description:
15 | name: analyzer
16 | sha256: "690e335554a8385bc9d787117d9eb52c0c03ee207a607e593de3c9d71b1cfe80"
17 | url: "https://pub.dev"
18 | source: hosted
19 | version: "4.7.0"
20 | args:
21 | dependency: transitive
22 | description:
23 | name: args
24 | sha256: b003c3098049a51720352d219b0bb5f219b60fbfb68e7a4748139a06a5676515
25 | url: "https://pub.dev"
26 | source: hosted
27 | version: "2.3.1"
28 | async:
29 | dependency: transitive
30 | description:
31 | name: async
32 | sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
33 | url: "https://pub.dev"
34 | source: hosted
35 | version: "2.13.0"
36 | boolean_selector:
37 | dependency: transitive
38 | description:
39 | name: boolean_selector
40 | sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
41 | url: "https://pub.dev"
42 | source: hosted
43 | version: "2.1.2"
44 | characters:
45 | dependency: transitive
46 | description:
47 | name: characters
48 | sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
49 | url: "https://pub.dev"
50 | source: hosted
51 | version: "1.4.0"
52 | clock:
53 | dependency: transitive
54 | description:
55 | name: clock
56 | sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
57 | url: "https://pub.dev"
58 | source: hosted
59 | version: "1.1.2"
60 | collection:
61 | dependency: transitive
62 | description:
63 | name: collection
64 | sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
65 | url: "https://pub.dev"
66 | source: hosted
67 | version: "1.19.1"
68 | convert:
69 | dependency: transitive
70 | description:
71 | name: convert
72 | sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
73 | url: "https://pub.dev"
74 | source: hosted
75 | version: "3.1.1"
76 | crypto:
77 | dependency: transitive
78 | description:
79 | name: crypto
80 | sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67
81 | url: "https://pub.dev"
82 | source: hosted
83 | version: "3.0.2"
84 | fake_async:
85 | dependency: transitive
86 | description:
87 | name: fake_async
88 | sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
89 | url: "https://pub.dev"
90 | source: hosted
91 | version: "1.3.3"
92 | file:
93 | dependency: transitive
94 | description:
95 | name: file
96 | sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
97 | url: "https://pub.dev"
98 | source: hosted
99 | version: "6.1.4"
100 | flutter:
101 | dependency: "direct main"
102 | description: flutter
103 | source: sdk
104 | version: "0.0.0"
105 | flutter_lints:
106 | dependency: "direct dev"
107 | description:
108 | name: flutter_lints
109 | sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1"
110 | url: "https://pub.dev"
111 | source: hosted
112 | version: "6.0.0"
113 | flutter_test:
114 | dependency: "direct dev"
115 | description: flutter
116 | source: sdk
117 | version: "0.0.0"
118 | glob:
119 | dependency: transitive
120 | description:
121 | name: glob
122 | sha256: c51b4fdfee4d281f49b8c957f1add91b815473597f76bcf07377987f66a55729
123 | url: "https://pub.dev"
124 | source: hosted
125 | version: "2.1.0"
126 | leak_tracker:
127 | dependency: transitive
128 | description:
129 | name: leak_tracker
130 | sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0"
131 | url: "https://pub.dev"
132 | source: hosted
133 | version: "10.0.9"
134 | leak_tracker_flutter_testing:
135 | dependency: transitive
136 | description:
137 | name: leak_tracker_flutter_testing
138 | sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
139 | url: "https://pub.dev"
140 | source: hosted
141 | version: "3.0.9"
142 | leak_tracker_testing:
143 | dependency: transitive
144 | description:
145 | name: leak_tracker_testing
146 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
147 | url: "https://pub.dev"
148 | source: hosted
149 | version: "3.0.1"
150 | lints:
151 | dependency: transitive
152 | description:
153 | name: lints
154 | sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0
155 | url: "https://pub.dev"
156 | source: hosted
157 | version: "6.0.0"
158 | matcher:
159 | dependency: transitive
160 | description:
161 | name: matcher
162 | sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
163 | url: "https://pub.dev"
164 | source: hosted
165 | version: "0.12.17"
166 | material_color_utilities:
167 | dependency: transitive
168 | description:
169 | name: material_color_utilities
170 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
171 | url: "https://pub.dev"
172 | source: hosted
173 | version: "0.11.1"
174 | meta:
175 | dependency: transitive
176 | description:
177 | name: meta
178 | sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
179 | url: "https://pub.dev"
180 | source: hosted
181 | version: "1.16.0"
182 | package_config:
183 | dependency: transitive
184 | description:
185 | name: package_config
186 | sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
187 | url: "https://pub.dev"
188 | source: hosted
189 | version: "2.1.0"
190 | path:
191 | dependency: transitive
192 | description:
193 | name: path
194 | sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
195 | url: "https://pub.dev"
196 | source: hosted
197 | version: "1.9.1"
198 | pigeon:
199 | dependency: "direct dev"
200 | description:
201 | name: pigeon
202 | sha256: "3d2abf23455db89416491c690ee969b7e4ba65f54e7ca303f1698c135eed5bdb"
203 | url: "https://pub.dev"
204 | source: hosted
205 | version: "4.2.5"
206 | pub_semver:
207 | dependency: transitive
208 | description:
209 | name: pub_semver
210 | sha256: b959af0a045c3484c4a8f4997731f5bfe4cac60d732fd8ce35b351f2d6a459fe
211 | url: "https://pub.dev"
212 | source: hosted
213 | version: "2.1.2"
214 | sky_engine:
215 | dependency: transitive
216 | description: flutter
217 | source: sdk
218 | version: "0.0.0"
219 | source_span:
220 | dependency: transitive
221 | description:
222 | name: source_span
223 | sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
224 | url: "https://pub.dev"
225 | source: hosted
226 | version: "1.10.1"
227 | stack_trace:
228 | dependency: transitive
229 | description:
230 | name: stack_trace
231 | sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
232 | url: "https://pub.dev"
233 | source: hosted
234 | version: "1.12.1"
235 | stream_channel:
236 | dependency: transitive
237 | description:
238 | name: stream_channel
239 | sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
240 | url: "https://pub.dev"
241 | source: hosted
242 | version: "2.1.4"
243 | string_scanner:
244 | dependency: transitive
245 | description:
246 | name: string_scanner
247 | sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
248 | url: "https://pub.dev"
249 | source: hosted
250 | version: "1.4.1"
251 | term_glyph:
252 | dependency: transitive
253 | description:
254 | name: term_glyph
255 | sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
256 | url: "https://pub.dev"
257 | source: hosted
258 | version: "1.2.2"
259 | test_api:
260 | dependency: transitive
261 | description:
262 | name: test_api
263 | sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
264 | url: "https://pub.dev"
265 | source: hosted
266 | version: "0.7.4"
267 | typed_data:
268 | dependency: transitive
269 | description:
270 | name: typed_data
271 | sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5"
272 | url: "https://pub.dev"
273 | source: hosted
274 | version: "1.3.1"
275 | vector_math:
276 | dependency: transitive
277 | description:
278 | name: vector_math
279 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
280 | url: "https://pub.dev"
281 | source: hosted
282 | version: "2.1.4"
283 | vm_service:
284 | dependency: transitive
285 | description:
286 | name: vm_service
287 | sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02
288 | url: "https://pub.dev"
289 | source: hosted
290 | version: "15.0.0"
291 | watcher:
292 | dependency: transitive
293 | description:
294 | name: watcher
295 | sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0"
296 | url: "https://pub.dev"
297 | source: hosted
298 | version: "1.0.2"
299 | yaml:
300 | dependency: transitive
301 | description:
302 | name: yaml
303 | sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370"
304 | url: "https://pub.dev"
305 | source: hosted
306 | version: "3.1.1"
307 | sdks:
308 | dart: ">=3.8.0 <4.0.0"
309 | flutter: ">=3.19.0"
310 |
--------------------------------------------------------------------------------
/lib/signalr_api.dart:
--------------------------------------------------------------------------------
1 | // Autogenerated from Pigeon (v4.2.5), do not edit directly.
2 | // See also: https://pub.dev/packages/pigeon
3 | // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import
4 | import 'dart:async';
5 | import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
6 |
7 | import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
8 | import 'package:flutter/services.dart';
9 |
10 | /// Transport method of the signalr connection.
11 | enum Transport {
12 | auto,
13 | serverSentEvents,
14 | longPolling,
15 | }
16 |
17 | /// SignalR connection status
18 | enum ConnectionStatus {
19 | connecting,
20 | connected,
21 | reconnecting,
22 | disconnected,
23 | connectionSlow,
24 | connectionError,
25 | }
26 |
27 | class ConnectionOptions {
28 | ConnectionOptions({
29 | this.baseUrl,
30 | this.hubName,
31 | this.queryString,
32 | this.hubMethods,
33 | this.headers,
34 | this.transport,
35 | });
36 |
37 | String? baseUrl;
38 | String? hubName;
39 | String? queryString;
40 | List? hubMethods;
41 | Map? headers;
42 | Transport? transport;
43 |
44 | Object encode() {
45 | final Map