Skip to content

Commit d9d1ca1

Browse files
authored
Feature/headers emulation (#19)
* Add headers emulation * Update centrifuge at benchmark * Update web benhmarks * Update benchmark
1 parent ae2120c commit d9d1ca1

29 files changed

Lines changed: 500 additions & 137 deletions

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.2.0
2+
3+
- Headers emulation
4+
15
## 0.1.0
26

37
- Add benchmark information to README

README.md

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ This library allows you to connect your Dart or Flutter applications to [Centrif
2828
- **Logging**: Log events, errors, and messages for debugging purposes.
2929
- **Cross-Platform**: Run on Dart VM, Flutter, and Web platforms.
3030
- **Performance**: Achieve high throughput and low latency for real-time messaging.
31+
- **Headers Emulation**: Emulate HTTP headers for WebSocket connections at the Web platform.
3132

3233
## Installation
3334

@@ -120,28 +121,21 @@ Each message is sent sequentially: the client waits for the server's response be
120121

121122
| | Spinify | Centrifuge-Dart |
122123
| ----- | ------------------- | ------------------- |
123-
| 1 KB | 5763 msg/s (7MB/s) | 5361 msg/s (6MB/s) |
124-
| 5 KB | 4405 msg/s (22MB/s) | 3731 msg/s (18MB/s) |
125-
| 10 KB | 3717 msg/s (37MB/s) | 2857 msg/s (28MB/s) |
126-
| 14 KB | 3305 msg/s (45MB/s) | 2564 msg/s (35MB/s) |
127-
| 16 KB | 3091 msg/s (50MB/s) | 1982 msg/s (32MB/s) |
128-
| 20 KB | 2812 msg/s (56MB/s) | 1811 msg/s (36MB/s) |
129-
| 30 KB | 2463 msg/s (72MB/s) | 1470 msg/s (43MB/s) |
130-
| 40 KB | 1937 msg/s (76MB/s) | 1089 msg/s (42MB/s) |
131-
| 50 KB | 1740 msg/s (85MB/s) | 967 msg/s (47MB/s) |
132-
| 60 KB | 1583 msg/s (92MB/s) | 877 msg/s (51MB/s) |
124+
| 1 KB | 5396 msg/s (6MB/s) | 5433 msg/s (6MB/s) |
125+
| 14 KB | 3216 msg/s (46MB/s) | 3224 msg/s (46MB/s) |
126+
| 30 KB | 2371 msg/s (71MB/s) | 2352 msg/s (70MB/s) |
127+
| 60 KB | 1558 msg/s (92MB/s) | 1547 msg/s (91MB/s) |
133128

134129
_\* Messages larger than 64 KB are not supported._
135130

136131
### Browser (WASM and JS)
137132

138133
| | Spinify WASM | Spinify JS | Centrifuge-Dart JS |
139134
| ----- | ------------------- | ------------------- | ------------------- |
140-
| 1 KB | 3676 msg/s (4MB/s) | 3502 msg/s (4MB/s) | 3067 msg/s (3MB/s) |
141-
| 5 KB | 2659 msg/s (13MB/s) | 3484 msg/s (17MB/s) | 2207 msg/s (11MB/s) |
142-
| 10 KB | 1926 msg/s (19MB/s) | 3189 msg/s (31MB/s) | 1584 msg/s (15MB/s) |
143-
| 14 KB | 1670 msg/s (22MB/s) | 2890 msg/s (39MB/s) | 1287 msg/s (17MB/s) |
144-
| 16 KB | 39 msg/s (662KB/s) | 39 msg/s (662KB/s) | 39 msg/s (662KB/s) |
135+
| 1 KB | 3676 msg/s (4MB/s) | 3590 msg/s (6MB/s) | 3720 msg/s (6MB/s) |
136+
| 5 KB | 2659 msg/s (13MB/s) | 3227 msg/s (18MB/s) | 3223 msg/s (18MB/s) |
137+
| 10 KB | 1926 msg/s (19MB/s) | 3031 msg/s (32MB/s) | 3029 msg/s (32MB/s) |
138+
| 14 KB | 1670 msg/s (22MB/s) | 2750 msg/s (39MB/s) | 2830 msg/s (40MB/s) |
145139

146140
_\* After message sizes exceed 15 KB, there is a noticeable performance drop._
147141

@@ -180,6 +174,7 @@ _\* After message sizes exceed 15 KB, there is a noticeable performance drop._
180174
- ✅ Benchmarks
181175
- ✅ Performance comparison with other libraries
182176
- ✅ WASM compatibility
177+
- ✅ Headers emulation
183178
- ❌ 95% test coverage
184179
- ❌ JSON codec support for transport
185180
- ❌ DevTools extension

example/benchmark/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
*.swp
66
.DS_Store
77
.atom/
8+
.build/
89
.buildlog/
910
.history
1011
.svn/
12+
.swiftpm/
1113
migrate_working_dir/
1214

1315
# IntelliJ related

example/benchmark/.metadata

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# This file should be version controlled and should not be manually edited.
55

66
version:
7-
revision: "2663184aa79047d0a33a14a3b607954f8fdd8730"
7+
revision: "c519ee916eaeb88923e67befb89c0f1dabfa83e6"
88
channel: "stable"
99

1010
project_type: app
@@ -13,26 +13,26 @@ project_type: app
1313
migration:
1414
platforms:
1515
- platform: root
16-
create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
17-
base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
16+
create_revision: c519ee916eaeb88923e67befb89c0f1dabfa83e6
17+
base_revision: c519ee916eaeb88923e67befb89c0f1dabfa83e6
1818
- platform: android
19-
create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
20-
base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
19+
create_revision: c519ee916eaeb88923e67befb89c0f1dabfa83e6
20+
base_revision: c519ee916eaeb88923e67befb89c0f1dabfa83e6
2121
- platform: ios
22-
create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
23-
base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
22+
create_revision: c519ee916eaeb88923e67befb89c0f1dabfa83e6
23+
base_revision: c519ee916eaeb88923e67befb89c0f1dabfa83e6
2424
- platform: linux
25-
create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
26-
base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
25+
create_revision: c519ee916eaeb88923e67befb89c0f1dabfa83e6
26+
base_revision: c519ee916eaeb88923e67befb89c0f1dabfa83e6
2727
- platform: macos
28-
create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
29-
base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
28+
create_revision: c519ee916eaeb88923e67befb89c0f1dabfa83e6
29+
base_revision: c519ee916eaeb88923e67befb89c0f1dabfa83e6
3030
- platform: web
31-
create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
32-
base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
31+
create_revision: c519ee916eaeb88923e67befb89c0f1dabfa83e6
32+
base_revision: c519ee916eaeb88923e67befb89c0f1dabfa83e6
3333
- platform: windows
34-
create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
35-
base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
34+
create_revision: c519ee916eaeb88923e67befb89c0f1dabfa83e6
35+
base_revision: c519ee916eaeb88923e67befb89c0f1dabfa83e6
3636

3737
# User provided section
3838

example/benchmark/linux/CMakeLists.txt

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Project-level configuration.
2-
cmake_minimum_required(VERSION 3.10)
2+
cmake_minimum_required(VERSION 3.13)
33
project(runner LANGUAGES CXX)
44

55
# The name of the executable created for the application. Change this to change
@@ -54,25 +54,8 @@ add_subdirectory(${FLUTTER_MANAGED_DIR})
5454
find_package(PkgConfig REQUIRED)
5555
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
5656

57-
add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
58-
59-
# Define the application target. To change its name, change BINARY_NAME above,
60-
# not the value here, or `flutter run` will no longer work.
61-
#
62-
# Any new source files that you add to the application should be added here.
63-
add_executable(${BINARY_NAME}
64-
"main.cc"
65-
"my_application.cc"
66-
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
67-
)
68-
69-
# Apply the standard set of build settings. This can be removed for applications
70-
# that need different build settings.
71-
apply_standard_settings(${BINARY_NAME})
72-
73-
# Add dependency libraries. Add any application-specific dependencies here.
74-
target_link_libraries(${BINARY_NAME} PRIVATE flutter)
75-
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
57+
# Application build; see runner/CMakeLists.txt.
58+
add_subdirectory("runner")
7659

7760
# Run the Flutter tool portions of the build. This must not be removed.
7861
add_dependencies(${BINARY_NAME} flutter_assemble)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
cmake_minimum_required(VERSION 3.13)
2+
project(runner LANGUAGES CXX)
3+
4+
# Define the application target. To change its name, change BINARY_NAME in the
5+
# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer
6+
# work.
7+
#
8+
# Any new source files that you add to the application should be added here.
9+
add_executable(${BINARY_NAME}
10+
"main.cc"
11+
"my_application.cc"
12+
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
13+
)
14+
15+
# Apply the standard set of build settings. This can be removed for applications
16+
# that need different build settings.
17+
apply_standard_settings(${BINARY_NAME})
18+
19+
# Add preprocessor definitions for the application ID.
20+
add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
21+
22+
# Add dependency libraries. Add any application-specific dependencies here.
23+
target_link_libraries(${BINARY_NAME} PRIVATE flutter)
24+
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
25+
26+
target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include "my_application.h"
2+
3+
int main(int argc, char** argv) {
4+
g_autoptr(MyApplication) app = my_application_new();
5+
return g_application_run(G_APPLICATION(app), argc, argv);
6+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#include "my_application.h"
2+
3+
#include <flutter_linux/flutter_linux.h>
4+
#ifdef GDK_WINDOWING_X11
5+
#include <gdk/gdkx.h>
6+
#endif
7+
8+
#include "flutter/generated_plugin_registrant.h"
9+
10+
struct _MyApplication {
11+
GtkApplication parent_instance;
12+
char** dart_entrypoint_arguments;
13+
};
14+
15+
G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
16+
17+
// Implements GApplication::activate.
18+
static void my_application_activate(GApplication* application) {
19+
MyApplication* self = MY_APPLICATION(application);
20+
GtkWindow* window =
21+
GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
22+
23+
// Use a header bar when running in GNOME as this is the common style used
24+
// by applications and is the setup most users will be using (e.g. Ubuntu
25+
// desktop).
26+
// If running on X and not using GNOME then just use a traditional title bar
27+
// in case the window manager does more exotic layout, e.g. tiling.
28+
// If running on Wayland assume the header bar will work (may need changing
29+
// if future cases occur).
30+
gboolean use_header_bar = TRUE;
31+
#ifdef GDK_WINDOWING_X11
32+
GdkScreen* screen = gtk_window_get_screen(window);
33+
if (GDK_IS_X11_SCREEN(screen)) {
34+
const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
35+
if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
36+
use_header_bar = FALSE;
37+
}
38+
}
39+
#endif
40+
if (use_header_bar) {
41+
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
42+
gtk_widget_show(GTK_WIDGET(header_bar));
43+
gtk_header_bar_set_title(header_bar, "spinifybenchmark");
44+
gtk_header_bar_set_show_close_button(header_bar, TRUE);
45+
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
46+
} else {
47+
gtk_window_set_title(window, "spinifybenchmark");
48+
}
49+
50+
gtk_window_set_default_size(window, 1280, 720);
51+
gtk_widget_show(GTK_WIDGET(window));
52+
53+
g_autoptr(FlDartProject) project = fl_dart_project_new();
54+
fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
55+
56+
FlView* view = fl_view_new(project);
57+
gtk_widget_show(GTK_WIDGET(view));
58+
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
59+
60+
fl_register_plugins(FL_PLUGIN_REGISTRY(view));
61+
62+
gtk_widget_grab_focus(GTK_WIDGET(view));
63+
}
64+
65+
// Implements GApplication::local_command_line.
66+
static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) {
67+
MyApplication* self = MY_APPLICATION(application);
68+
// Strip out the first argument as it is the binary name.
69+
self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
70+
71+
g_autoptr(GError) error = nullptr;
72+
if (!g_application_register(application, nullptr, &error)) {
73+
g_warning("Failed to register: %s", error->message);
74+
*exit_status = 1;
75+
return TRUE;
76+
}
77+
78+
g_application_activate(application);
79+
*exit_status = 0;
80+
81+
return TRUE;
82+
}
83+
84+
// Implements GApplication::startup.
85+
static void my_application_startup(GApplication* application) {
86+
//MyApplication* self = MY_APPLICATION(object);
87+
88+
// Perform any actions required at application startup.
89+
90+
G_APPLICATION_CLASS(my_application_parent_class)->startup(application);
91+
}
92+
93+
// Implements GApplication::shutdown.
94+
static void my_application_shutdown(GApplication* application) {
95+
//MyApplication* self = MY_APPLICATION(object);
96+
97+
// Perform any actions required at application shutdown.
98+
99+
G_APPLICATION_CLASS(my_application_parent_class)->shutdown(application);
100+
}
101+
102+
// Implements GObject::dispose.
103+
static void my_application_dispose(GObject* object) {
104+
MyApplication* self = MY_APPLICATION(object);
105+
g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
106+
G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
107+
}
108+
109+
static void my_application_class_init(MyApplicationClass* klass) {
110+
G_APPLICATION_CLASS(klass)->activate = my_application_activate;
111+
G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line;
112+
G_APPLICATION_CLASS(klass)->startup = my_application_startup;
113+
G_APPLICATION_CLASS(klass)->shutdown = my_application_shutdown;
114+
G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
115+
}
116+
117+
static void my_application_init(MyApplication* self) {}
118+
119+
MyApplication* my_application_new() {
120+
// Set the program name to the application ID, which helps various systems
121+
// like GTK and desktop environments map this running application to its
122+
// corresponding .desktop file. This ensures better integration by allowing
123+
// the application to be recognized beyond its binary name.
124+
g_set_prgname(APPLICATION_ID);
125+
126+
return MY_APPLICATION(g_object_new(my_application_get_type(),
127+
"application-id", APPLICATION_ID,
128+
"flags", G_APPLICATION_NON_UNIQUE,
129+
nullptr));
130+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#ifndef FLUTTER_MY_APPLICATION_H_
2+
#define FLUTTER_MY_APPLICATION_H_
3+
4+
#include <gtk/gtk.h>
5+
6+
G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION,
7+
GtkApplication)
8+
9+
/**
10+
* my_application_new:
11+
*
12+
* Creates a new Flutter-based application.
13+
*
14+
* Returns: a new #MyApplication.
15+
*/
16+
MyApplication* my_application_new();
17+
18+
#endif // FLUTTER_MY_APPLICATION_H_

example/benchmark/macos/Runner/AppDelegate.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,8 @@ class AppDelegate: FlutterAppDelegate {
66
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
77
return true
88
}
9+
10+
override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
11+
return true
12+
}
913
}

0 commit comments

Comments
 (0)