opal-up 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +4 -3
- data/ext/up_ext/up_ext.c +65 -19
- 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 +1 -0
- 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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e47b86e6f54cbdb8ecf23cf5b6c759127ac30a8f4f00764e39eeca57ca94e52d
|
|
4
|
+
data.tar.gz: 6d93f3b96474fb1c18fadeb5a46083241947691470a0c3f7d36dc7025e1116de
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 25d3c86c354d50656b266995a0d235460e6d9c45b1853d33d363636e1bead3b4539b8a068fee0cbfd58b27d2160759b2f1823ae039c2ce0c15793f6a95fd0541
|
|
7
|
+
data.tar.gz: d3a6dd3a8e854a1ba75cfc297ecb5b4153c04b3814185add67424bcfd7574538d4365aebbd1006967e798d7af155ad0b98582955eb4f8c2e1f5633448d474433
|
data/README.md
CHANGED
|
@@ -84,15 +84,16 @@ Available with `bundle exec` within the example apps or if this gem is included
|
|
|
84
84
|
Usage: up [options]
|
|
85
85
|
|
|
86
86
|
-h, --help Show this message
|
|
87
|
-
-p, --port PORT Port number the server will listen to
|
|
88
|
-
-b, --bind ADDRESS Address the server will listen to
|
|
87
|
+
-p, --port PORT Port number the server will listen to. Default: 3000
|
|
88
|
+
-b, --bind ADDRESS Address the server will listen to. Default: localhost
|
|
89
89
|
-s, --secure Use secure sockets.
|
|
90
90
|
When using secure sockets, the -a, -c and -k options must be provided
|
|
91
91
|
-a, --ca-file FILE File with CA certs
|
|
92
92
|
-c, --cert-file FILE File with the servers certificate
|
|
93
93
|
-k, --key-file FILE File with the servers certificate
|
|
94
|
+
-l, --log-file FILE Log file
|
|
94
95
|
-v, --version Show version
|
|
95
|
-
|
|
96
|
+
-w, --workers NUMBER For clusters, the number of workers to run. Default: number of processors
|
|
96
97
|
```
|
|
97
98
|
## Supported Features
|
|
98
99
|
|
data/ext/up_ext/up_ext.c
CHANGED
|
@@ -22,7 +22,9 @@ static VALUE cLogger;
|
|
|
22
22
|
|
|
23
23
|
static ID at_env;
|
|
24
24
|
static ID at_handler;
|
|
25
|
+
static ID at_instance;
|
|
25
26
|
static ID at_member_id;
|
|
27
|
+
static ID at_members;
|
|
26
28
|
static ID at_open;
|
|
27
29
|
static ID at_protocol;
|
|
28
30
|
static ID at_secret;
|
|
@@ -40,6 +42,7 @@ static ID id_on_drained;
|
|
|
40
42
|
static ID id_on_message;
|
|
41
43
|
static ID id_on_open;
|
|
42
44
|
static ID id_port;
|
|
45
|
+
static ID id_publish;
|
|
43
46
|
|
|
44
47
|
static rb_encoding *utf8_encoding;
|
|
45
48
|
static rb_encoding *binary_encoding;
|
|
@@ -411,14 +414,14 @@ static VALUE up_client_pending(VALUE self) {
|
|
|
411
414
|
return INT2FIX(0);
|
|
412
415
|
}
|
|
413
416
|
|
|
414
|
-
static void up_client_cluster_publish(
|
|
417
|
+
static void up_client_cluster_publish(char *scrt, int st, VALUE channel,
|
|
415
418
|
VALUE message) {
|
|
416
419
|
const char *opening_line = "POST " INTERNAL_PUBLISH_PATH " HTTP/1.1\r\n";
|
|
417
420
|
const char *host_header = "Host: localhost\r\n";
|
|
418
421
|
const char *secret = "Secret: ";
|
|
419
422
|
char secret_header[50];
|
|
420
423
|
memcpy(secret_header, secret, 8);
|
|
421
|
-
memcpy(secret_header + 8,
|
|
424
|
+
memcpy(secret_header + 8, scrt, 36);
|
|
422
425
|
memcpy(secret_header + 8 + 36, "\r\n", 2);
|
|
423
426
|
const char *content_type = "Content-Type: text/plain\r\n";
|
|
424
427
|
long c_length = RSTRING_LEN(channel) + RSTRING_LEN(message) + 2;
|
|
@@ -447,12 +450,25 @@ static void up_client_cluster_publish(server_s *s, int st, VALUE channel,
|
|
|
447
450
|
// fprintf(stderr, "read: %s\n", read_buf);
|
|
448
451
|
}
|
|
449
452
|
|
|
450
|
-
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) {
|
|
451
469
|
uws_websocket_t *ws = DATA_PTR(self);
|
|
452
470
|
if (!ws)
|
|
453
471
|
return Qnil;
|
|
454
|
-
VALUE channel, message, engine;
|
|
455
|
-
rb_scan_args(argc, argv, "21", &channel, &message, &engine);
|
|
456
472
|
if (TYPE(channel) != T_STRING)
|
|
457
473
|
channel = rb_obj_as_string(channel);
|
|
458
474
|
if (TYPE(message) != T_STRING)
|
|
@@ -467,20 +483,9 @@ static VALUE up_client_publish(int argc, VALUE *argv, VALUE self) {
|
|
|
467
483
|
|
|
468
484
|
// publish to cluster members
|
|
469
485
|
int i;
|
|
470
|
-
struct sockaddr_in member_addr = {
|
|
471
|
-
.sin_addr.s_addr = inet_addr("127.0.0.1"), .sin_family = AF_INET};
|
|
472
486
|
for (i = 1; i <= s->workers; i++) {
|
|
473
|
-
if (i != s->member_id)
|
|
474
|
-
|
|
475
|
-
if (st) {
|
|
476
|
-
member_addr.sin_port = htons(FIX2INT(s->port) + i);
|
|
477
|
-
if (connect(st, (struct sockaddr *)&member_addr,
|
|
478
|
-
sizeof(struct sockaddr_in)) == 0) {
|
|
479
|
-
up_client_cluster_publish(s, st, channel, message);
|
|
480
|
-
close(st);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
}
|
|
487
|
+
if (i != s->member_id)
|
|
488
|
+
up_internal_publish_to_member(s, channel, message, i);
|
|
484
489
|
}
|
|
485
490
|
}
|
|
486
491
|
return res ? Qtrue : Qfalse;
|
|
@@ -747,6 +752,7 @@ static void up_internal_close_sockets(int signal) {
|
|
|
747
752
|
static VALUE up_server_listen(VALUE self) {
|
|
748
753
|
server_s *s = DATA_PTR(self);
|
|
749
754
|
up_internal_check_arg_types(s->rapp, &s->host, &s->port);
|
|
755
|
+
rb_ivar_set(mUp, at_instance, self);
|
|
750
756
|
|
|
751
757
|
s->env_template = rb_hash_dup(rack_env_template);
|
|
752
758
|
// When combined with SCRIPT_NAME and PATH_INFO, these variables can be used
|
|
@@ -820,6 +826,33 @@ static VALUE up_server_listen(VALUE self) {
|
|
|
820
826
|
return self;
|
|
821
827
|
}
|
|
822
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
|
+
|
|
823
856
|
static VALUE up_server_stop(VALUE self) {
|
|
824
857
|
server_s *s = DATA_PTR(self);
|
|
825
858
|
if (!s->app)
|
|
@@ -891,10 +924,19 @@ void up_setup_rack_env_template(void) {
|
|
|
891
924
|
rb_hash_aset(rack_env_template, HTTP_VERSION, http11);
|
|
892
925
|
}
|
|
893
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
|
+
|
|
894
934
|
void Init_up_ext(void) {
|
|
895
935
|
at_env = rb_intern("@env");
|
|
896
936
|
at_handler = rb_intern("@handler");
|
|
937
|
+
at_instance = rb_intern("@instance");
|
|
897
938
|
at_member_id = rb_intern("@member_id");
|
|
939
|
+
at_members = rb_intern("@members");
|
|
898
940
|
at_open = rb_intern("@open");
|
|
899
941
|
at_protocol = rb_intern("@protocol");
|
|
900
942
|
at_secret = rb_intern("@secret");
|
|
@@ -912,6 +954,7 @@ void Init_up_ext(void) {
|
|
|
912
954
|
id_on_message = rb_intern("on_message");
|
|
913
955
|
id_on_open = rb_intern("on_open");
|
|
914
956
|
id_port = rb_intern("port");
|
|
957
|
+
id_publish = rb_intern("publish");
|
|
915
958
|
|
|
916
959
|
utf8_encoding = rb_enc_find("UTF-8");
|
|
917
960
|
binary_encoding = rb_enc_find("binary");
|
|
@@ -949,11 +992,13 @@ void Init_up_ext(void) {
|
|
|
949
992
|
up_setup_rack_env_template();
|
|
950
993
|
|
|
951
994
|
mUp = rb_define_module("Up");
|
|
995
|
+
rb_define_singleton_method(mUp, "publish", up_publish, 2);
|
|
996
|
+
|
|
952
997
|
cClient = rb_define_class_under(mUp, "Client", rb_cObject);
|
|
953
998
|
rb_define_alloc_func(cClient, up_client_alloc);
|
|
954
999
|
rb_define_method(cClient, "close", up_client_close, 0);
|
|
955
1000
|
rb_define_method(cClient, "pending", up_client_pending, 0);
|
|
956
|
-
rb_define_method(cClient, "publish", up_client_publish,
|
|
1001
|
+
rb_define_method(cClient, "publish", up_client_publish, 2);
|
|
957
1002
|
rb_define_method(cClient, "subscribe", up_client_subscribe, -1);
|
|
958
1003
|
rb_define_method(cClient, "unsubscribe", up_client_unsubscribe, -1);
|
|
959
1004
|
rb_define_method(cClient, "write", up_client_write, 1);
|
|
@@ -964,5 +1009,6 @@ void Init_up_ext(void) {
|
|
|
964
1009
|
rb_define_alloc_func(cServer, up_server_alloc);
|
|
965
1010
|
rb_define_method(cServer, "initialize", up_server_init, -1);
|
|
966
1011
|
rb_define_method(cServer, "listen", up_server_listen, 0);
|
|
1012
|
+
rb_define_method(cServer, "publish", up_server_publish, 2);
|
|
967
1013
|
rb_define_method(cServer, "stop", up_server_stop, 0);
|
|
968
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
|
@@ -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: []
|