opal-up 0.0.4 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -3
- data/ext/up_ext/App.h +665 -544
- data/ext/up_ext/AsyncSocket.h +307 -284
- data/ext/up_ext/AsyncSocketData.h +35 -51
- data/ext/up_ext/BloomFilter.h +37 -42
- data/ext/up_ext/ChunkedEncoding.h +174 -175
- data/ext/up_ext/ClientApp.h +20 -23
- data/ext/up_ext/HttpContext.h +476 -381
- data/ext/up_ext/HttpContextData.h +20 -20
- data/ext/up_ext/HttpErrors.h +14 -10
- data/ext/up_ext/HttpParser.h +631 -563
- data/ext/up_ext/HttpResponse.h +526 -460
- data/ext/up_ext/HttpResponseData.h +59 -55
- data/ext/up_ext/HttpRouter.h +328 -310
- data/ext/up_ext/Loop.h +174 -168
- data/ext/up_ext/LoopData.h +60 -67
- data/ext/up_ext/MoveOnlyFunction.h +71 -80
- data/ext/up_ext/PerMessageDeflate.h +218 -198
- data/ext/up_ext/ProxyParser.h +100 -99
- data/ext/up_ext/QueryParser.h +91 -84
- data/ext/up_ext/TopicTree.h +273 -268
- data/ext/up_ext/Utilities.h +25 -25
- data/ext/up_ext/WebSocket.h +376 -310
- data/ext/up_ext/WebSocketContext.h +487 -372
- data/ext/up_ext/WebSocketContextData.h +74 -62
- data/ext/up_ext/WebSocketData.h +53 -46
- data/ext/up_ext/WebSocketExtensions.h +194 -178
- data/ext/up_ext/WebSocketHandshake.h +115 -110
- data/ext/up_ext/WebSocketProtocol.h +441 -398
- data/ext/up_ext/up_ext.c +108 -24
- data/lib/up/bun/server.rb +17 -0
- data/lib/up/cli.rb +6 -3
- data/lib/up/client.rb +2 -3
- data/lib/up/ruby/cluster.rb +30 -6
- data/lib/up/u_web_socket/cluster.rb +22 -2
- data/lib/up/u_web_socket/server.rb +19 -2
- data/lib/up/version.rb +1 -1
- metadata +4 -24
data/ext/up_ext/up_ext.c
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
#include <arpa/inet.h>
|
4
4
|
#include <ruby.h>
|
5
5
|
#include <ruby/encoding.h>
|
6
|
+
#include <signal.h>
|
6
7
|
#include <sys/socket.h>
|
7
8
|
#include <sys/wait.h>
|
8
9
|
#include <unistd.h>
|
@@ -21,7 +22,9 @@ static VALUE cLogger;
|
|
21
22
|
|
22
23
|
static ID at_env;
|
23
24
|
static ID at_handler;
|
25
|
+
static ID at_instance;
|
24
26
|
static ID at_member_id;
|
27
|
+
static ID at_members;
|
25
28
|
static ID at_open;
|
26
29
|
static ID at_protocol;
|
27
30
|
static ID at_secret;
|
@@ -39,6 +42,7 @@ static ID id_on_drained;
|
|
39
42
|
static ID id_on_message;
|
40
43
|
static ID id_on_open;
|
41
44
|
static ID id_port;
|
45
|
+
static ID id_publish;
|
42
46
|
|
43
47
|
static rb_encoding *utf8_encoding;
|
44
48
|
static rb_encoding *binary_encoding;
|
@@ -65,6 +69,10 @@ static VALUE SERVER_NAME;
|
|
65
69
|
static VALUE SERVER_PORT;
|
66
70
|
static VALUE SERVER_PROTOCOL;
|
67
71
|
|
72
|
+
// both used when worker of a cluster
|
73
|
+
uws_app_t *cluster_app;
|
74
|
+
struct us_listen_socket_t *cluster_socket;
|
75
|
+
|
68
76
|
#define set_str_val(gl_name, str) \
|
69
77
|
rb_gc_register_address(&gl_name); \
|
70
78
|
(gl_name) = rb_enc_str_new((str), strlen((str)), binary_encoding); \
|
@@ -358,12 +366,23 @@ response_error:
|
|
358
366
|
uws_res_end_without_body(USE_SSL, res, false);
|
359
367
|
}
|
360
368
|
|
369
|
+
static void
|
370
|
+
up_server_cluster_listen_handler(struct us_listen_socket_t *listen_socket,
|
371
|
+
uws_app_listen_config_t config, void *arg) {
|
372
|
+
if (listen_socket) {
|
373
|
+
cluster_socket = listen_socket;
|
374
|
+
fprintf(stderr, "Internal Cluster communication on http://localhost:%d\n",
|
375
|
+
config.port);
|
376
|
+
}
|
377
|
+
}
|
378
|
+
|
361
379
|
static void up_server_listen_handler(struct us_listen_socket_t *listen_socket,
|
362
380
|
uws_app_listen_config_t config,
|
363
|
-
void *
|
364
|
-
if (listen_socket)
|
365
|
-
fprintf(stderr, "Server is
|
381
|
+
void *arg) {
|
382
|
+
if (listen_socket) {
|
383
|
+
fprintf(stderr, "Server is listening on http://%s:%d\n", config.host,
|
366
384
|
config.port);
|
385
|
+
}
|
367
386
|
}
|
368
387
|
|
369
388
|
const rb_data_type_t up_client_t = {.wrap_struct_name = "Up::Client",
|
@@ -395,14 +414,14 @@ static VALUE up_client_pending(VALUE self) {
|
|
395
414
|
return INT2FIX(0);
|
396
415
|
}
|
397
416
|
|
398
|
-
static void up_client_cluster_publish(
|
417
|
+
static void up_client_cluster_publish(char *scrt, int st, VALUE channel,
|
399
418
|
VALUE message) {
|
400
419
|
const char *opening_line = "POST " INTERNAL_PUBLISH_PATH " HTTP/1.1\r\n";
|
401
420
|
const char *host_header = "Host: localhost\r\n";
|
402
421
|
const char *secret = "Secret: ";
|
403
422
|
char secret_header[50];
|
404
423
|
memcpy(secret_header, secret, 8);
|
405
|
-
memcpy(secret_header + 8,
|
424
|
+
memcpy(secret_header + 8, scrt, 36);
|
406
425
|
memcpy(secret_header + 8 + 36, "\r\n", 2);
|
407
426
|
const char *content_type = "Content-Type: text/plain\r\n";
|
408
427
|
long c_length = RSTRING_LEN(channel) + RSTRING_LEN(message) + 2;
|
@@ -431,12 +450,25 @@ static void up_client_cluster_publish(server_s *s, int st, VALUE channel,
|
|
431
450
|
// fprintf(stderr, "read: %s\n", read_buf);
|
432
451
|
}
|
433
452
|
|
434
|
-
static
|
453
|
+
static void up_internal_publish_to_member(server_s *s, VALUE channel,
|
454
|
+
VALUE message, int member_idx) {
|
455
|
+
struct sockaddr_in member_addr = {.sin_addr.s_addr = inet_addr("127.0.0.1"),
|
456
|
+
.sin_family = AF_INET};
|
457
|
+
int st = socket(AF_INET, SOCK_STREAM, 0);
|
458
|
+
if (st) {
|
459
|
+
member_addr.sin_port = htons(FIX2INT(s->port) + member_idx);
|
460
|
+
if (connect(st, (struct sockaddr *)&member_addr,
|
461
|
+
sizeof(struct sockaddr_in)) == 0) {
|
462
|
+
up_client_cluster_publish(s->secret, st, channel, message);
|
463
|
+
close(st);
|
464
|
+
}
|
465
|
+
}
|
466
|
+
}
|
467
|
+
|
468
|
+
static VALUE up_client_publish(VALUE self, VALUE channel, VALUE message) {
|
435
469
|
uws_websocket_t *ws = DATA_PTR(self);
|
436
470
|
if (!ws)
|
437
471
|
return Qnil;
|
438
|
-
VALUE channel, message, engine;
|
439
|
-
rb_scan_args(argc, argv, "21", &channel, &message, &engine);
|
440
472
|
if (TYPE(channel) != T_STRING)
|
441
473
|
channel = rb_obj_as_string(channel);
|
442
474
|
if (TYPE(message) != T_STRING)
|
@@ -451,20 +483,9 @@ static VALUE up_client_publish(int argc, VALUE *argv, VALUE self) {
|
|
451
483
|
|
452
484
|
// publish to cluster members
|
453
485
|
int i;
|
454
|
-
struct sockaddr_in member_addr = {
|
455
|
-
.sin_addr.s_addr = inet_addr("127.0.0.1"), .sin_family = AF_INET};
|
456
486
|
for (i = 1; i <= s->workers; i++) {
|
457
|
-
if (i != s->member_id)
|
458
|
-
|
459
|
-
if (st) {
|
460
|
-
member_addr.sin_port = htons(FIX2INT(s->port) + i);
|
461
|
-
if (connect(st, (struct sockaddr *)&member_addr,
|
462
|
-
sizeof(struct sockaddr_in)) == 0) {
|
463
|
-
up_client_cluster_publish(s, st, channel, message);
|
464
|
-
close(st);
|
465
|
-
}
|
466
|
-
}
|
467
|
-
}
|
487
|
+
if (i != s->member_id)
|
488
|
+
up_internal_publish_to_member(s, channel, message, i);
|
468
489
|
}
|
469
490
|
}
|
470
491
|
return res ? Qtrue : Qfalse;
|
@@ -721,9 +742,17 @@ upgrade_error:
|
|
721
742
|
fprintf(stderr, "upgrade error");
|
722
743
|
}
|
723
744
|
|
745
|
+
static void up_internal_close_sockets(int signal) {
|
746
|
+
if (cluster_socket)
|
747
|
+
us_listen_socket_close(false, cluster_socket);
|
748
|
+
if (cluster_app)
|
749
|
+
uws_app_close(USE_SSL, cluster_app);
|
750
|
+
}
|
751
|
+
|
724
752
|
static VALUE up_server_listen(VALUE self) {
|
725
753
|
server_s *s = DATA_PTR(self);
|
726
754
|
up_internal_check_arg_types(s->rapp, &s->host, &s->port);
|
755
|
+
rb_ivar_set(mUp, at_instance, self);
|
727
756
|
|
728
757
|
s->env_template = rb_hash_dup(rack_env_template);
|
729
758
|
// When combined with SCRIPT_NAME and PATH_INFO, these variables can be used
|
@@ -747,8 +776,16 @@ static VALUE up_server_listen(VALUE self) {
|
|
747
776
|
.port = FIX2INT(s->port), .host = RSTRING_PTR(s->host), .options = 0};
|
748
777
|
VALUE rmember_id = rb_ivar_get(self, at_member_id);
|
749
778
|
if (rmember_id != Qnil) {
|
779
|
+
// got a cluster
|
750
780
|
s->member_id = FIX2INT(rmember_id);
|
751
|
-
//
|
781
|
+
// install signal handler
|
782
|
+
cluster_app = s->app;
|
783
|
+
cluster_socket = NULL;
|
784
|
+
struct sigaction upclcl = {.sa_handler = up_internal_close_sockets,
|
785
|
+
.sa_flags = 0};
|
786
|
+
sigemptyset(&upclcl.sa_mask);
|
787
|
+
sigaction(SIGINT, &upclcl, NULL);
|
788
|
+
// open publish ports
|
752
789
|
VALUE rworkers = rb_ivar_get(self, at_workers);
|
753
790
|
s->workers = FIX2INT(rworkers);
|
754
791
|
VALUE rsecret = rb_ivar_get(self, at_secret);
|
@@ -761,7 +798,14 @@ static VALUE up_server_listen(VALUE self) {
|
|
761
798
|
uws_app_listen_config_t config_internal = {
|
762
799
|
.port = config.port + s->member_id, .host = "localhost", .options = 0};
|
763
800
|
uws_app_listen_with_config(false, s->app, config_internal,
|
764
|
-
|
801
|
+
up_server_cluster_listen_handler, NULL);
|
802
|
+
} else {
|
803
|
+
cluster_app = s->app;
|
804
|
+
cluster_socket = NULL;
|
805
|
+
struct sigaction upclcl = {.sa_handler = up_internal_close_sockets,
|
806
|
+
.sa_flags = 0};
|
807
|
+
sigemptyset(&upclcl.sa_mask);
|
808
|
+
sigaction(SIGINT, &upclcl, NULL);
|
765
809
|
}
|
766
810
|
uws_app_any(USE_SSL, s->app, "/*", up_server_request_handler, (void *)s);
|
767
811
|
uws_ws(USE_SSL, s->app, "/*",
|
@@ -782,6 +826,33 @@ static VALUE up_server_listen(VALUE self) {
|
|
782
826
|
return self;
|
783
827
|
}
|
784
828
|
|
829
|
+
static VALUE up_server_publish(VALUE self, VALUE channel, VALUE message) {
|
830
|
+
if (TYPE(channel) != T_STRING)
|
831
|
+
channel = rb_obj_as_string(channel);
|
832
|
+
if (TYPE(message) != T_STRING)
|
833
|
+
message = rb_obj_as_string(message);
|
834
|
+
server_s *s = DATA_PTR(self);
|
835
|
+
VALUE members = rb_ivar_get(self, at_members);
|
836
|
+
if (members != Qnil) {
|
837
|
+
long i, mb_cnt = RARRAY_LEN(members);
|
838
|
+
for (i = 0; i < mb_cnt; i++) {
|
839
|
+
up_internal_publish_to_member(s, channel, message, i);
|
840
|
+
}
|
841
|
+
} else {
|
842
|
+
uws_publish(USE_SSL, s->app, RSTRING_PTR(channel), RSTRING_LEN(channel),
|
843
|
+
RSTRING_PTR(message), RSTRING_LEN(message), TEXT, false);
|
844
|
+
if (s->member_id > 0) {
|
845
|
+
// publish to cluster members
|
846
|
+
int i;
|
847
|
+
for (i = 1; i <= s->workers; i++) {
|
848
|
+
if (i != s->member_id)
|
849
|
+
up_internal_publish_to_member(s, channel, message, i);
|
850
|
+
}
|
851
|
+
}
|
852
|
+
}
|
853
|
+
return Qtrue;
|
854
|
+
}
|
855
|
+
|
785
856
|
static VALUE up_server_stop(VALUE self) {
|
786
857
|
server_s *s = DATA_PTR(self);
|
787
858
|
if (!s->app)
|
@@ -853,10 +924,19 @@ void up_setup_rack_env_template(void) {
|
|
853
924
|
rb_hash_aset(rack_env_template, HTTP_VERSION, http11);
|
854
925
|
}
|
855
926
|
|
927
|
+
static VALUE up_publish(VALUE self, VALUE channel, VALUE message) {
|
928
|
+
VALUE instance = rb_ivar_get(mUp, at_instance);
|
929
|
+
if (instance != Qnil)
|
930
|
+
return rb_funcall(instance, id_publish, 2, channel, message);
|
931
|
+
return Qfalse;
|
932
|
+
}
|
933
|
+
|
856
934
|
void Init_up_ext(void) {
|
857
935
|
at_env = rb_intern("@env");
|
858
936
|
at_handler = rb_intern("@handler");
|
937
|
+
at_instance = rb_intern("@instance");
|
859
938
|
at_member_id = rb_intern("@member_id");
|
939
|
+
at_members = rb_intern("@members");
|
860
940
|
at_open = rb_intern("@open");
|
861
941
|
at_protocol = rb_intern("@protocol");
|
862
942
|
at_secret = rb_intern("@secret");
|
@@ -874,6 +954,7 @@ void Init_up_ext(void) {
|
|
874
954
|
id_on_message = rb_intern("on_message");
|
875
955
|
id_on_open = rb_intern("on_open");
|
876
956
|
id_port = rb_intern("port");
|
957
|
+
id_publish = rb_intern("publish");
|
877
958
|
|
878
959
|
utf8_encoding = rb_enc_find("UTF-8");
|
879
960
|
binary_encoding = rb_enc_find("binary");
|
@@ -911,11 +992,13 @@ void Init_up_ext(void) {
|
|
911
992
|
up_setup_rack_env_template();
|
912
993
|
|
913
994
|
mUp = rb_define_module("Up");
|
995
|
+
rb_define_singleton_method(mUp, "publish", up_publish, 2);
|
996
|
+
|
914
997
|
cClient = rb_define_class_under(mUp, "Client", rb_cObject);
|
915
998
|
rb_define_alloc_func(cClient, up_client_alloc);
|
916
999
|
rb_define_method(cClient, "close", up_client_close, 0);
|
917
1000
|
rb_define_method(cClient, "pending", up_client_pending, 0);
|
918
|
-
rb_define_method(cClient, "publish", up_client_publish,
|
1001
|
+
rb_define_method(cClient, "publish", up_client_publish, 2);
|
919
1002
|
rb_define_method(cClient, "subscribe", up_client_subscribe, -1);
|
920
1003
|
rb_define_method(cClient, "unsubscribe", up_client_unsubscribe, -1);
|
921
1004
|
rb_define_method(cClient, "write", up_client_write, 1);
|
@@ -926,5 +1009,6 @@ void Init_up_ext(void) {
|
|
926
1009
|
rb_define_alloc_func(cServer, up_server_alloc);
|
927
1010
|
rb_define_method(cServer, "initialize", up_server_init, -1);
|
928
1011
|
rb_define_method(cServer, "listen", up_server_listen, 0);
|
1012
|
+
rb_define_method(cServer, "publish", up_server_publish, 2);
|
929
1013
|
rb_define_method(cServer, "stop", up_server_stop, 0);
|
930
1014
|
}
|
data/lib/up/bun/server.rb
CHANGED
@@ -4,6 +4,13 @@ require 'up/cli'
|
|
4
4
|
require 'up/client'
|
5
5
|
|
6
6
|
module Up
|
7
|
+
class << self
|
8
|
+
def publish(channel, message)
|
9
|
+
raise 'no instance running' unless @instance
|
10
|
+
@instance&.publish(channel, message)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
7
14
|
module Bun
|
8
15
|
class Server
|
9
16
|
def initialize(app:, host: 'localhost', port: 3000, scheme: 'http', ca_file: nil, cert_file: nil, key_file: nil, logger: Logger.new(STDERR))
|
@@ -49,6 +56,7 @@ module Up
|
|
49
56
|
}
|
50
57
|
def listen
|
51
58
|
raise "already running" if @server
|
59
|
+
::Up.instance_variable_set(:@instance, self)
|
52
60
|
%x{
|
53
61
|
const oubs = Opal.Up.Bun.Server;
|
54
62
|
const ouwc = Opal.Up.Client;
|
@@ -152,6 +160,15 @@ module Up
|
|
152
160
|
}
|
153
161
|
end
|
154
162
|
|
163
|
+
def publish(channel, message)
|
164
|
+
%x{
|
165
|
+
if (!message.$$is_string) {
|
166
|
+
message = JSON.stringify(message);
|
167
|
+
}
|
168
|
+
#@server.publish(channel, message);
|
169
|
+
}
|
170
|
+
end
|
171
|
+
|
155
172
|
def stop
|
156
173
|
if Up::CLI::stoppable?
|
157
174
|
`#@server.stop()`
|
data/lib/up/cli.rb
CHANGED
@@ -14,10 +14,10 @@ module Up
|
|
14
14
|
puts self
|
15
15
|
exit
|
16
16
|
end
|
17
|
-
on('-p', '--port PORT', String, 'Port number the server will listen to') do |port|
|
17
|
+
on('-p', '--port PORT', String, 'Port number the server will listen to. Default: 3000') do |port|
|
18
18
|
options[:port] = port.to_i
|
19
19
|
end
|
20
|
-
on('-b', '--bind ADDRESS', String, 'Address the server will listen to') do |host|
|
20
|
+
on('-b', '--bind ADDRESS', String, 'Address the server will listen to. Default: localhost') do |host|
|
21
21
|
options[:host] = host
|
22
22
|
end
|
23
23
|
on('-s', '--secure', "Use secure sockets.\nWhen using secure sockets, the -a, -c and -k options must be provided") do
|
@@ -32,13 +32,16 @@ module Up
|
|
32
32
|
on('-k', '--key-file FILE', String, 'File with the servers certificate') do |key_file|
|
33
33
|
options[:key_file] = key_file
|
34
34
|
end
|
35
|
-
on('-l', '--log-file FILE', String, '
|
35
|
+
on('-l', '--log-file FILE', String, 'Log file') do |log_file|
|
36
36
|
options[:logger] = Logger.new(File.new(log_file, 'a+'))
|
37
37
|
end
|
38
38
|
on('-v', '--version', 'Show version') do
|
39
39
|
puts "Up! v#{Up::VERSION}"
|
40
40
|
exit
|
41
41
|
end
|
42
|
+
on('-w', '--workers NUMBER', 'For clusters, the number of workers to run. Default: number of processors') do |workers|
|
43
|
+
options[:workers] = workers.to_i
|
44
|
+
end
|
42
45
|
end
|
43
46
|
|
44
47
|
def parse!
|
data/lib/up/client.rb
CHANGED
@@ -36,15 +36,14 @@ module Up
|
|
36
36
|
`#@ws?.getBufferedAmount()`
|
37
37
|
end
|
38
38
|
|
39
|
-
def publish(channel, message
|
39
|
+
def publish(channel, message)
|
40
40
|
res = false
|
41
|
-
raise 'publish engine not supported' if engine
|
42
41
|
%x{
|
43
42
|
if (!message.$$is_string) {
|
44
43
|
message = JSON.stringify(message);
|
45
44
|
}
|
46
45
|
res = #@server?.publish(channel, message);
|
47
|
-
if (
|
46
|
+
if (#@worker) {
|
48
47
|
process.send({c: channel, m: message});
|
49
48
|
}
|
50
49
|
}
|
data/lib/up/ruby/cluster.rb
CHANGED
@@ -15,24 +15,48 @@ module Up
|
|
15
15
|
|
16
16
|
def listen
|
17
17
|
raise "already running" unless @members.empty?
|
18
|
+
::Up.instance_variable_set(:@instance, self)
|
18
19
|
@workers.times do
|
19
20
|
@members << fork do
|
20
21
|
@member_id = @members.size + 1
|
21
22
|
super
|
22
23
|
end
|
23
24
|
end
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
Process.kill("KILL", member)
|
25
|
+
unless @member_id
|
26
|
+
install_signal_handlers
|
27
|
+
Process.waitall
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
31
|
def stop
|
32
32
|
if Up::CLI::stoppable?
|
33
|
-
|
34
|
-
|
33
|
+
kill_members
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def install_signal_handlers
|
40
|
+
Signal.trap('CHLD') do
|
41
|
+
warn "\nError: a cluster member died!"
|
42
|
+
kill_members
|
43
|
+
end
|
44
|
+
Signal.trap('INT') do
|
45
|
+
warn "\nReceived CTRL-C!"
|
46
|
+
kill_members
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def kill_members
|
51
|
+
Signal.trap('CHLD', 'IGNORE')
|
52
|
+
STDERR.print "Stopping workers: "
|
53
|
+
@members.each do |mid|
|
54
|
+
Process.kill('INT', mid) rescue nil
|
55
|
+
STDERR.print '.'
|
35
56
|
end
|
57
|
+
@members.clear
|
58
|
+
warn "\nCluster stopped."
|
59
|
+
Signal.trap('CHLD', 'DEFAULT')
|
36
60
|
end
|
37
61
|
end
|
38
62
|
end
|
@@ -18,6 +18,7 @@ module Up
|
|
18
18
|
|
19
19
|
def listen
|
20
20
|
raise "already running" unless @members.empty?
|
21
|
+
::Up.instance_variable_set(:@instance, self)
|
21
22
|
%x{
|
22
23
|
if (cluster.isPrimary) {
|
23
24
|
cluster.on('message', (worker, message, handle) => {
|
@@ -33,9 +34,9 @@ module Up
|
|
33
34
|
#@members[i] = cluster.fork();
|
34
35
|
}
|
35
36
|
} else {
|
36
|
-
|
37
|
+
#@worker = true;
|
37
38
|
function process_message_handler(message, handle) {
|
38
|
-
|
39
|
+
#@server.publish(message.c, message.m);
|
39
40
|
}
|
40
41
|
process.on('message', process_message_handler);
|
41
42
|
#{super}
|
@@ -43,6 +44,25 @@ module Up
|
|
43
44
|
}
|
44
45
|
end
|
45
46
|
|
47
|
+
def publish(channel, message)
|
48
|
+
%x{
|
49
|
+
if (!message.$$is_string) {
|
50
|
+
message = JSON.stringify(message);
|
51
|
+
}
|
52
|
+
if (#@worker ) {
|
53
|
+
#@server?.publish(channel, message);
|
54
|
+
process.send({c: channel, m: message});
|
55
|
+
} else if (#@members) {
|
56
|
+
for (let member of #@members) {
|
57
|
+
if (member !== worker) {
|
58
|
+
member.send(message);
|
59
|
+
}
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|
63
|
+
true
|
64
|
+
end
|
65
|
+
|
46
66
|
def stop
|
47
67
|
if Up::CLI::stoppable?
|
48
68
|
@members.each { |m| `m.kill()` }
|
@@ -10,6 +10,13 @@ require 'up/client'
|
|
10
10
|
}
|
11
11
|
|
12
12
|
module Up
|
13
|
+
class << self
|
14
|
+
def publish(channel, message)
|
15
|
+
raise 'no instance running' unless @instance
|
16
|
+
@instance&.publish(channel, message)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
13
20
|
module UWebSocket
|
14
21
|
class Server
|
15
22
|
def initialize(app:, host: 'localhost', port: 3000, scheme: 'http', ca_file: nil, cert_file: nil, key_file: nil, logger: Logger.new(STDERR))
|
@@ -74,6 +81,7 @@ module Up
|
|
74
81
|
|
75
82
|
def listen
|
76
83
|
raise "already running" if @server
|
84
|
+
::Up.instance_variable_set(:@instance, self)
|
77
85
|
%x{
|
78
86
|
const ouws = Opal.Up.UWebSocket.Server;
|
79
87
|
const ouwc = Opal.Up.Client;
|
@@ -138,9 +146,9 @@ module Up
|
|
138
146
|
client.open = false;
|
139
147
|
client.handler = handler
|
140
148
|
client.protocol = #{:websocket};
|
141
|
-
client.server =
|
149
|
+
client.server = #@server;
|
142
150
|
client.timeout = 120;
|
143
|
-
if (
|
151
|
+
if (#@worker) {
|
144
152
|
client.worker = true;
|
145
153
|
}
|
146
154
|
res.upgrade({ client: client },
|
@@ -164,6 +172,15 @@ module Up
|
|
164
172
|
}
|
165
173
|
end
|
166
174
|
|
175
|
+
def publish(channel, message)
|
176
|
+
%x{
|
177
|
+
if (!message.$$is_string) {
|
178
|
+
message = JSON.stringify(message);
|
179
|
+
}
|
180
|
+
#@server.publish(channel, message);
|
181
|
+
}
|
182
|
+
end
|
183
|
+
|
167
184
|
def stop
|
168
185
|
if Up::CLI::stoppable?
|
169
186
|
`#@server.close()`
|
data/lib/up/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opal-up
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Biedermann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-02-
|
11
|
+
date: 2024-02-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logger
|
@@ -58,26 +58,6 @@ dependencies:
|
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: 3.0.9
|
61
|
-
- !ruby/object:Gem::Dependency
|
62
|
-
name: rackup
|
63
|
-
requirement: !ruby/object:Gem::Requirement
|
64
|
-
requirements:
|
65
|
-
- - ">="
|
66
|
-
- !ruby/object:Gem::Version
|
67
|
-
version: 0.2.2
|
68
|
-
- - "<"
|
69
|
-
- !ruby/object:Gem::Version
|
70
|
-
version: 3.0.0
|
71
|
-
type: :runtime
|
72
|
-
prerelease: false
|
73
|
-
version_requirements: !ruby/object:Gem::Requirement
|
74
|
-
requirements:
|
75
|
-
- - ">="
|
76
|
-
- !ruby/object:Gem::Version
|
77
|
-
version: 0.2.2
|
78
|
-
- - "<"
|
79
|
-
- !ruby/object:Gem::Version
|
80
|
-
version: 3.0.0
|
81
61
|
- !ruby/object:Gem::Dependency
|
82
62
|
name: rake
|
83
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -201,7 +181,7 @@ files:
|
|
201
181
|
- lib/up/u_web_socket/server.rb
|
202
182
|
- lib/up/u_web_socket/server_cli.rb
|
203
183
|
- lib/up/version.rb
|
204
|
-
homepage:
|
184
|
+
homepage: https://github.com/janbiedermann/up
|
205
185
|
licenses:
|
206
186
|
- MIT
|
207
187
|
metadata: {}
|
@@ -223,5 +203,5 @@ requirements: []
|
|
223
203
|
rubygems_version: 3.5.3
|
224
204
|
signing_key:
|
225
205
|
specification_version: 4
|
226
|
-
summary: Rack server for Opal
|
206
|
+
summary: Rack server for Opal and Ruby
|
227
207
|
test_files: []
|