pakyow-realtime 1.0.0.rc5 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -27
- data/lib/pakyow/application/actions/realtime/upgrader.rb +31 -0
- data/lib/pakyow/application/behavior/realtime/serialization.rb +45 -0
- data/lib/pakyow/application/behavior/realtime/server.rb +44 -0
- data/lib/pakyow/application/behavior/realtime/silencing.rb +27 -0
- data/lib/pakyow/{realtime/behavior/config.rb → application/config/realtime.rb} +3 -3
- data/lib/pakyow/application/helpers/realtime/broadcasting.rb +15 -0
- data/lib/pakyow/application/helpers/realtime/socket.rb +15 -0
- data/lib/pakyow/application/helpers/realtime/subscriptions.rb +37 -0
- data/lib/pakyow/config/realtime.rb +27 -0
- data/lib/pakyow/presenter/renderer/behavior/realtime/install_websocket.rb +59 -0
- data/lib/pakyow/realtime.rb +3 -3
- data/lib/pakyow/realtime/framework.rb +16 -16
- data/lib/pakyow/realtime/server/adapters/redis.rb +6 -2
- data/lib/pakyow/realtime/websocket.rb +4 -4
- metadata +24 -24
- data/lib/pakyow/actions/realtime/upgrader.rb +0 -29
- data/lib/pakyow/environment/realtime/config.rb +0 -29
- data/lib/pakyow/realtime/behavior/rendering/install_websocket.rb +0 -57
- data/lib/pakyow/realtime/behavior/serialization.rb +0 -43
- data/lib/pakyow/realtime/behavior/server.rb +0 -42
- data/lib/pakyow/realtime/behavior/silencing.rb +0 -25
- data/lib/pakyow/realtime/helpers/broadcasting.rb +0 -13
- data/lib/pakyow/realtime/helpers/socket.rb +0 -13
- data/lib/pakyow/realtime/helpers/subscriptions.rb +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b293bc25cc1b570e275cde636777adebc00bb11d18747757cc55ba39bd7da70e
|
4
|
+
data.tar.gz: 4df355cd9e243be0b9a6c4d4beb3e76c357b5d3fd9c6a5beacc4f3872ef963db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55b9af0a648366f7a83a1b1294718e8ec9c6b54641f8f93aa735dcfba04ddc91d18f4fce1b363730b50d03caadbec3ec82027d3556650d93894a8b6fc20f1415
|
7
|
+
data.tar.gz: 2e91d53ec05f65673f35cdfa165a65a67756021a45817ccc8c6b45e009e794d289e7d08a5132bf875c20b60834d87945c988f7396cd795cf523534d343854659
|
data/CHANGELOG.md
CHANGED
@@ -1,29 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# UNRELEASED
|
2
2
|
|
3
|
-
|
4
|
-
* CHANGED WebSocket log level to verbose.
|
3
|
+
# 1.0
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
* Gracefully shuts down WebSocket when something bad happens
|
9
|
-
* Fixes a bug calling the root route over a WebSocket
|
10
|
-
* Fixes a bug causing join events to be fired before the connection is registered
|
11
|
-
* Fixes a bug causing session to not be serialized in redis
|
12
|
-
* Fixes a bug causing redis subscriptions to never unsubscribe
|
13
|
-
* Properly disconnects from redis as necessary to avoid eating up connections
|
14
|
-
* Moves everything into the Pakyow namespace
|
15
|
-
* Improves subscriber management in production environments
|
16
|
-
* Fixes a memory leak caused by converting channel names to symbols
|
17
|
-
* Replaces `websocket_parser` gem with `websocket`
|
18
|
-
* Fixes a bug causing websocket failures in Internet Explorer
|
19
|
-
|
20
|
-
# 0.10.2 / 2015-11-15
|
21
|
-
|
22
|
-
* Adds ability to return only a partial in call-route response
|
23
|
-
* Fixes several bugs with the redis registry / subscriptions
|
24
|
-
* Fixes a bug causing qualifications to not match when using redis
|
25
|
-
* Bumps concurrent-ruby version to 1.0
|
26
|
-
|
27
|
-
# 0.10.0 / 2015-10-19
|
28
|
-
|
29
|
-
* Initial release
|
5
|
+
* Hello, Web
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/message_verifier"
|
4
|
+
|
5
|
+
require "pakyow/realtime/websocket"
|
6
|
+
|
7
|
+
module Pakyow
|
8
|
+
class Application
|
9
|
+
module Actions
|
10
|
+
module Realtime
|
11
|
+
class Upgrader
|
12
|
+
def call(connection)
|
13
|
+
if websocket?(connection)
|
14
|
+
Pakyow::Realtime::WebSocket.new(connection.verifier.verify(connection.params[:id]), connection)
|
15
|
+
connection.halt
|
16
|
+
end
|
17
|
+
rescue Support::MessageVerifier::TamperedMessage
|
18
|
+
connection.status = 403
|
19
|
+
connection.halt
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def websocket?(connection)
|
25
|
+
connection.path == "/pw-socket"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fileutils"
|
4
|
+
|
5
|
+
require "pakyow/support/extension"
|
6
|
+
require "pakyow/support/serializer"
|
7
|
+
|
8
|
+
module Pakyow
|
9
|
+
class Application
|
10
|
+
module Behavior
|
11
|
+
module Realtime
|
12
|
+
# Persists the in-memory realtime server across restarts.
|
13
|
+
#
|
14
|
+
module Serialization
|
15
|
+
extend Support::Extension
|
16
|
+
|
17
|
+
apply_extension do
|
18
|
+
on "shutdown", priority: :high do
|
19
|
+
if Pakyow.config.realtime.adapter == :memory && instance_variable_defined?(:@websocket_server)
|
20
|
+
realtime_server_serializer.serialize
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
after "boot" do
|
25
|
+
if Pakyow.config.realtime.adapter == :memory
|
26
|
+
realtime_server_serializer.deserialize
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private def realtime_server_serializer
|
32
|
+
Support::Serializer.new(
|
33
|
+
@websocket_server.adapter,
|
34
|
+
name: "#{config.name}-realtime",
|
35
|
+
path: File.join(
|
36
|
+
Pakyow.config.root, "tmp", "state"
|
37
|
+
),
|
38
|
+
logger: Pakyow.logger
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/deep_freeze"
|
4
|
+
require "pakyow/support/extension"
|
5
|
+
|
6
|
+
require "pakyow/realtime/server"
|
7
|
+
|
8
|
+
module Pakyow
|
9
|
+
class Application
|
10
|
+
module Behavior
|
11
|
+
module Realtime
|
12
|
+
module Server
|
13
|
+
extend Support::Extension
|
14
|
+
|
15
|
+
apply_extension do
|
16
|
+
extend Support::DeepFreeze
|
17
|
+
unfreezable :websocket_server
|
18
|
+
attr_reader :websocket_server
|
19
|
+
|
20
|
+
after "initialize", priority: :high do
|
21
|
+
@websocket_server = if is_a?(Plugin)
|
22
|
+
parent.websocket_server
|
23
|
+
else
|
24
|
+
Pakyow::Realtime::Server.new(
|
25
|
+
Pakyow.config.realtime.adapter,
|
26
|
+
Pakyow.config.realtime.adapter_settings.to_h.merge(
|
27
|
+
config.realtime.adapter_settings.to_h
|
28
|
+
),
|
29
|
+
config.realtime.timeouts
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
on "shutdown" do
|
35
|
+
if instance_variable_defined?(:@websocket_server)
|
36
|
+
@websocket_server.shutdown
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/extension"
|
4
|
+
|
5
|
+
module Pakyow
|
6
|
+
class Application
|
7
|
+
module Behavior
|
8
|
+
module Realtime
|
9
|
+
# Silences asset requests from being logged.
|
10
|
+
#
|
11
|
+
module Silencing
|
12
|
+
extend Support::Extension
|
13
|
+
|
14
|
+
apply_extension do
|
15
|
+
on "load" do
|
16
|
+
unless config.realtime.log_initial_request
|
17
|
+
Pakyow.silence do |connection|
|
18
|
+
connection.path.start_with?(File.join("/", config.realtime.path))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pakyow
|
4
|
+
class Application
|
5
|
+
module Helpers
|
6
|
+
module Realtime
|
7
|
+
module Broadcasting
|
8
|
+
def broadcast(message)
|
9
|
+
app.websocket_server.subscription_broadcast(socket_client_id, message)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/realtime/channel"
|
4
|
+
|
5
|
+
module Pakyow
|
6
|
+
class Application
|
7
|
+
module Helpers
|
8
|
+
module Realtime
|
9
|
+
module Subscriptions
|
10
|
+
def subscribe(channel, *qualifiers)
|
11
|
+
channels = if qualifiers.empty?
|
12
|
+
Pakyow::Realtime::Channel.new(channel)
|
13
|
+
else
|
14
|
+
qualifiers.map { |qualifier|
|
15
|
+
Pakyow::Realtime::Channel.new(channel, qualifier)
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
app.websocket_server.socket_subscribe(socket_client_id, *channels)
|
20
|
+
end
|
21
|
+
|
22
|
+
def unsubscribe(channel, *qualifiers)
|
23
|
+
channels = if qualifiers.empty?
|
24
|
+
Pakyow::Realtime::Channel.new(channel, "*")
|
25
|
+
else
|
26
|
+
qualifiers.map { |qualifier|
|
27
|
+
Pakyow::Realtime::Channel.new(channel, qualifier)
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
app.websocket_server.socket_unsubscribe(*channels)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/extension"
|
4
|
+
|
5
|
+
module Pakyow
|
6
|
+
module Config
|
7
|
+
module Realtime
|
8
|
+
extend Support::Extension
|
9
|
+
|
10
|
+
apply_extension do
|
11
|
+
configurable :realtime do
|
12
|
+
setting :server, true
|
13
|
+
|
14
|
+
setting :adapter, :memory
|
15
|
+
setting :adapter_settings, {}
|
16
|
+
|
17
|
+
defaults :production do
|
18
|
+
setting :adapter, :redis
|
19
|
+
setting :adapter_settings do
|
20
|
+
Pakyow.config.redis.to_h
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/extension"
|
4
|
+
|
5
|
+
require "pakyow/presenter/view"
|
6
|
+
|
7
|
+
module Pakyow
|
8
|
+
module Presenter
|
9
|
+
class Renderer
|
10
|
+
module Behavior
|
11
|
+
module Realtime
|
12
|
+
module InstallWebsocket
|
13
|
+
extend Support::Extension
|
14
|
+
|
15
|
+
apply_extension do
|
16
|
+
build do |view|
|
17
|
+
if head = view.head
|
18
|
+
head.append(Support::SafeStringHelpers.html_safe("<meta name=\"pw-socket\" ui=\"socket\">"))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
attach do |presenter, app:|
|
23
|
+
presenter.render node: -> {
|
24
|
+
node = object.each_significant_node(:meta).find { |meta_node|
|
25
|
+
meta_node.attributes[:name] == "pw-socket"
|
26
|
+
}
|
27
|
+
|
28
|
+
unless node.nil?
|
29
|
+
Pakyow::Presenter::View.from_object(node)
|
30
|
+
end
|
31
|
+
} do
|
32
|
+
endpoint = app.config.realtime.endpoint
|
33
|
+
|
34
|
+
unless endpoint
|
35
|
+
endpoint = if Pakyow.config.server.proxy
|
36
|
+
# Connect directly to the app in development, since the proxy does not support websocket connections.
|
37
|
+
#
|
38
|
+
File.join("ws://#{Pakyow.config.server.host}:#{Pakyow.config.server.port}", app.config.realtime.path)
|
39
|
+
else
|
40
|
+
File.join("#{presentables[:__ws_protocol]}://#{presentables[:__ws_authority]}", app.config.realtime.path)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
attributes["data-ui"] = "socket(endpoint: #{endpoint}?id=#{presentables[:__verifier].sign(presentables[:__socket_client_id])})"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
expose do |connection|
|
49
|
+
connection.set(:__verifier, connection.verifier)
|
50
|
+
connection.set(:__ws_protocol, connection.secure? ? "wss" : "ws")
|
51
|
+
connection.set(:__ws_authority, connection.authority)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/pakyow/realtime.rb
CHANGED
@@ -6,10 +6,10 @@ require "pakyow/presenter"
|
|
6
6
|
|
7
7
|
require "pakyow/realtime/framework"
|
8
8
|
|
9
|
-
require "pakyow/
|
9
|
+
require "pakyow/config/realtime"
|
10
10
|
|
11
|
-
require "pakyow/actions/realtime/upgrader"
|
11
|
+
require "pakyow/application/actions/realtime/upgrader"
|
12
12
|
|
13
13
|
module Pakyow
|
14
|
-
include
|
14
|
+
include Config::Realtime
|
15
15
|
end
|
@@ -2,37 +2,37 @@
|
|
2
2
|
|
3
3
|
require "pakyow/framework"
|
4
4
|
|
5
|
-
require "pakyow/
|
6
|
-
require "pakyow/
|
7
|
-
require "pakyow/
|
5
|
+
require "pakyow/application/helpers/realtime/broadcasting"
|
6
|
+
require "pakyow/application/helpers/realtime/subscriptions"
|
7
|
+
require "pakyow/application/helpers/realtime/socket"
|
8
8
|
|
9
|
-
require "pakyow/
|
10
|
-
require "pakyow/
|
11
|
-
require "pakyow/
|
12
|
-
require "pakyow/
|
9
|
+
require "pakyow/application/config/realtime"
|
10
|
+
require "pakyow/application/behavior/realtime/serialization"
|
11
|
+
require "pakyow/application/behavior/realtime/server"
|
12
|
+
require "pakyow/application/behavior/realtime/silencing"
|
13
13
|
|
14
|
-
require "pakyow/
|
14
|
+
require "pakyow/presenter/renderer/behavior/realtime/install_websocket"
|
15
15
|
|
16
16
|
module Pakyow
|
17
17
|
module Realtime
|
18
18
|
class Framework < Pakyow::Framework(:realtime)
|
19
19
|
def boot
|
20
20
|
object.class_eval do
|
21
|
-
register_helper :active, Helpers::Broadcasting
|
22
|
-
register_helper :active, Helpers::Subscriptions
|
23
|
-
register_helper :passive, Helpers::Socket
|
21
|
+
register_helper :active, Application::Helpers::Realtime::Broadcasting
|
22
|
+
register_helper :active, Application::Helpers::Realtime::Subscriptions
|
23
|
+
register_helper :passive, Application::Helpers::Realtime::Socket
|
24
24
|
|
25
25
|
# Socket events are triggered on the app.
|
26
26
|
#
|
27
27
|
events :join, :leave
|
28
28
|
|
29
|
-
include
|
30
|
-
include Behavior::Server
|
31
|
-
include Behavior::Silencing
|
32
|
-
include Behavior::Serialization
|
29
|
+
include Application::Config::Realtime
|
30
|
+
include Application::Behavior::Realtime::Server
|
31
|
+
include Application::Behavior::Realtime::Silencing
|
32
|
+
include Application::Behavior::Realtime::Serialization
|
33
33
|
|
34
34
|
isolated :Renderer do
|
35
|
-
include Behavior::
|
35
|
+
include Presenter::Renderer::Behavior::Realtime::InstallWebsocket
|
36
36
|
end
|
37
37
|
|
38
38
|
isolated :Connection do
|
@@ -169,7 +169,9 @@ module Pakyow
|
|
169
169
|
|
170
170
|
def cleanup
|
171
171
|
Concurrent::TimerTask.new(execution_interval: 300, timeout_interval: 300) {
|
172
|
-
Pakyow.logger.
|
172
|
+
Pakyow.logger.internal {
|
173
|
+
"[Pakyow::Realtime::Server::Adapters::Redis] Cleaning up channel keys"
|
174
|
+
}
|
173
175
|
|
174
176
|
removed_count = 0
|
175
177
|
@redis.with do |redis|
|
@@ -185,7 +187,9 @@ module Pakyow
|
|
185
187
|
end
|
186
188
|
end
|
187
189
|
|
188
|
-
Pakyow.logger.
|
190
|
+
Pakyow.logger.internal {
|
191
|
+
"[Pakyow::Realtime::Server::Adapters::Redis] Removed #{removed_count} keys"
|
192
|
+
}
|
189
193
|
}.execute
|
190
194
|
end
|
191
195
|
|
@@ -3,8 +3,8 @@
|
|
3
3
|
require "json"
|
4
4
|
require "securerandom"
|
5
5
|
|
6
|
-
require "pakyow/helpers/app"
|
7
|
-
require "pakyow/helpers/connection"
|
6
|
+
require "pakyow/application/helpers/app"
|
7
|
+
require "pakyow/application/helpers/connection"
|
8
8
|
|
9
9
|
require "async/websocket"
|
10
10
|
|
@@ -35,8 +35,8 @@ module Pakyow
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
include Pakyow::Helpers::
|
39
|
-
include Pakyow::Helpers::Connection
|
38
|
+
include Pakyow::Application::Helpers::Application
|
39
|
+
include Pakyow::Application::Helpers::Connection
|
40
40
|
|
41
41
|
attr_reader :id
|
42
42
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pakyow-realtime
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bryan Powell
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-07-
|
11
|
+
date: 2019-07-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pakyow-core
|
@@ -16,56 +16,56 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.0.0
|
19
|
+
version: 1.0.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.0.0
|
26
|
+
version: 1.0.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: pakyow-presenter
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.0.0
|
33
|
+
version: 1.0.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.0.0
|
40
|
+
version: 1.0.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: pakyow-routing
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - '='
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 1.0.0
|
47
|
+
version: 1.0.0
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - '='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 1.0.0
|
54
|
+
version: 1.0.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: pakyow-support
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - '='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.0.0
|
61
|
+
version: 1.0.0
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 1.0.0
|
68
|
+
version: 1.0.0
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: async-websocket
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,7 +109,7 @@ dependencies:
|
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '4.1'
|
111
111
|
description: WebSockets and realtime channels for Pakyow
|
112
|
-
email: bryan@
|
112
|
+
email: bryan@bryanp.org
|
113
113
|
executables: []
|
114
114
|
extensions: []
|
115
115
|
extra_rdoc_files: []
|
@@ -117,24 +117,24 @@ files:
|
|
117
117
|
- CHANGELOG.md
|
118
118
|
- LICENSE
|
119
119
|
- README.md
|
120
|
-
- lib/pakyow/actions/realtime/upgrader.rb
|
121
|
-
- lib/pakyow/
|
120
|
+
- lib/pakyow/application/actions/realtime/upgrader.rb
|
121
|
+
- lib/pakyow/application/behavior/realtime/serialization.rb
|
122
|
+
- lib/pakyow/application/behavior/realtime/server.rb
|
123
|
+
- lib/pakyow/application/behavior/realtime/silencing.rb
|
124
|
+
- lib/pakyow/application/config/realtime.rb
|
125
|
+
- lib/pakyow/application/helpers/realtime/broadcasting.rb
|
126
|
+
- lib/pakyow/application/helpers/realtime/socket.rb
|
127
|
+
- lib/pakyow/application/helpers/realtime/subscriptions.rb
|
128
|
+
- lib/pakyow/config/realtime.rb
|
129
|
+
- lib/pakyow/presenter/renderer/behavior/realtime/install_websocket.rb
|
122
130
|
- lib/pakyow/realtime.rb
|
123
|
-
- lib/pakyow/realtime/behavior/config.rb
|
124
|
-
- lib/pakyow/realtime/behavior/rendering/install_websocket.rb
|
125
|
-
- lib/pakyow/realtime/behavior/serialization.rb
|
126
|
-
- lib/pakyow/realtime/behavior/server.rb
|
127
|
-
- lib/pakyow/realtime/behavior/silencing.rb
|
128
131
|
- lib/pakyow/realtime/channel.rb
|
129
132
|
- lib/pakyow/realtime/framework.rb
|
130
|
-
- lib/pakyow/realtime/helpers/broadcasting.rb
|
131
|
-
- lib/pakyow/realtime/helpers/socket.rb
|
132
|
-
- lib/pakyow/realtime/helpers/subscriptions.rb
|
133
133
|
- lib/pakyow/realtime/server.rb
|
134
134
|
- lib/pakyow/realtime/server/adapters/memory.rb
|
135
135
|
- lib/pakyow/realtime/server/adapters/redis.rb
|
136
136
|
- lib/pakyow/realtime/websocket.rb
|
137
|
-
homepage: https://pakyow.
|
137
|
+
homepage: https://pakyow.com
|
138
138
|
licenses:
|
139
139
|
- LGPL-3.0
|
140
140
|
metadata: {}
|
@@ -149,9 +149,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
149
149
|
version: 2.5.0
|
150
150
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
151
|
requirements:
|
152
|
-
- - "
|
152
|
+
- - ">="
|
153
153
|
- !ruby/object:Gem::Version
|
154
|
-
version:
|
154
|
+
version: '0'
|
155
155
|
requirements: []
|
156
156
|
rubygems_version: 3.0.3
|
157
157
|
signing_key:
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "pakyow/support/message_verifier"
|
4
|
-
|
5
|
-
require "pakyow/realtime/websocket"
|
6
|
-
|
7
|
-
module Pakyow
|
8
|
-
module Actions
|
9
|
-
module Realtime
|
10
|
-
class Upgrader
|
11
|
-
def call(connection)
|
12
|
-
if websocket?(connection)
|
13
|
-
Pakyow::Realtime::WebSocket.new(connection.verifier.verify(connection.params[:id]), connection)
|
14
|
-
connection.halt
|
15
|
-
end
|
16
|
-
rescue Support::MessageVerifier::TamperedMessage
|
17
|
-
connection.status = 403
|
18
|
-
connection.halt
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def websocket?(connection)
|
24
|
-
connection.path == "/pw-socket"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "pakyow/support/extension"
|
4
|
-
|
5
|
-
module Pakyow
|
6
|
-
module Environment
|
7
|
-
module Realtime
|
8
|
-
module Config
|
9
|
-
extend Support::Extension
|
10
|
-
|
11
|
-
apply_extension do
|
12
|
-
configurable :realtime do
|
13
|
-
setting :server, true
|
14
|
-
|
15
|
-
setting :adapter, :memory
|
16
|
-
setting :adapter_settings, {}
|
17
|
-
|
18
|
-
defaults :production do
|
19
|
-
setting :adapter, :redis
|
20
|
-
setting :adapter_settings do
|
21
|
-
Pakyow.config.redis.to_h
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "pakyow/support/extension"
|
4
|
-
|
5
|
-
require "pakyow/presenter/view"
|
6
|
-
|
7
|
-
module Pakyow
|
8
|
-
module Realtime
|
9
|
-
module Behavior
|
10
|
-
module Rendering
|
11
|
-
module InstallWebsocket
|
12
|
-
extend Support::Extension
|
13
|
-
|
14
|
-
apply_extension do
|
15
|
-
build do |view|
|
16
|
-
if head = view.head
|
17
|
-
head.append(Support::SafeStringHelpers.html_safe("<meta name=\"pw-socket\" ui=\"socket\">"))
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
attach do |presenter, app:|
|
22
|
-
presenter.render node: -> {
|
23
|
-
node = object.each_significant_node(:meta).find { |meta_node|
|
24
|
-
meta_node.attributes[:name] == "pw-socket"
|
25
|
-
}
|
26
|
-
|
27
|
-
unless node.nil?
|
28
|
-
Presenter::View.from_object(node)
|
29
|
-
end
|
30
|
-
} do
|
31
|
-
endpoint = app.config.realtime.endpoint
|
32
|
-
|
33
|
-
unless endpoint
|
34
|
-
endpoint = if Pakyow.config.server.proxy
|
35
|
-
# Connect directly to the app in development, since the proxy does not support websocket connections.
|
36
|
-
#
|
37
|
-
File.join("ws://#{Pakyow.config.server.host}:#{Pakyow.config.server.port}", app.config.realtime.path)
|
38
|
-
else
|
39
|
-
File.join("#{presentables[:__ws_protocol]}://#{presentables[:__ws_authority]}", app.config.realtime.path)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
attributes["data-ui"] = "socket(endpoint: #{endpoint}?id=#{presentables[:__verifier].sign(presentables[:__socket_client_id])})"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
expose do |connection|
|
48
|
-
connection.set(:__verifier, connection.verifier)
|
49
|
-
connection.set(:__ws_protocol, connection.secure? ? "wss" : "ws")
|
50
|
-
connection.set(:__ws_authority, connection.authority)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "fileutils"
|
4
|
-
|
5
|
-
require "pakyow/support/extension"
|
6
|
-
require "pakyow/support/serializer"
|
7
|
-
|
8
|
-
module Pakyow
|
9
|
-
module Realtime
|
10
|
-
module Behavior
|
11
|
-
# Persists the in-memory realtime server across restarts.
|
12
|
-
#
|
13
|
-
module Serialization
|
14
|
-
extend Support::Extension
|
15
|
-
|
16
|
-
apply_extension do
|
17
|
-
on "shutdown", priority: :high do
|
18
|
-
if Pakyow.config.realtime.adapter == :memory && instance_variable_defined?(:@websocket_server)
|
19
|
-
realtime_server_serializer.serialize
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
after "boot" do
|
24
|
-
if Pakyow.config.realtime.adapter == :memory
|
25
|
-
realtime_server_serializer.deserialize
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
private def realtime_server_serializer
|
31
|
-
Support::Serializer.new(
|
32
|
-
@websocket_server.adapter,
|
33
|
-
name: "#{config.name}-realtime",
|
34
|
-
path: File.join(
|
35
|
-
Pakyow.config.root, "tmp", "state"
|
36
|
-
),
|
37
|
-
logger: Pakyow.logger
|
38
|
-
)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "pakyow/support/deep_freeze"
|
4
|
-
require "pakyow/support/extension"
|
5
|
-
|
6
|
-
require "pakyow/realtime/server"
|
7
|
-
|
8
|
-
module Pakyow
|
9
|
-
module Realtime
|
10
|
-
module Behavior
|
11
|
-
module Server
|
12
|
-
extend Support::Extension
|
13
|
-
|
14
|
-
apply_extension do
|
15
|
-
extend Support::DeepFreeze
|
16
|
-
unfreezable :websocket_server
|
17
|
-
attr_reader :websocket_server
|
18
|
-
|
19
|
-
after "initialize", priority: :high do
|
20
|
-
@websocket_server = if is_a?(Plugin)
|
21
|
-
parent.websocket_server
|
22
|
-
else
|
23
|
-
Realtime::Server.new(
|
24
|
-
Pakyow.config.realtime.adapter,
|
25
|
-
Pakyow.config.realtime.adapter_settings.to_h.merge(
|
26
|
-
config.realtime.adapter_settings.to_h
|
27
|
-
),
|
28
|
-
config.realtime.timeouts
|
29
|
-
)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
on "shutdown" do
|
34
|
-
if instance_variable_defined?(:@websocket_server)
|
35
|
-
@websocket_server.shutdown
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "pakyow/support/extension"
|
4
|
-
|
5
|
-
module Pakyow
|
6
|
-
module Realtime
|
7
|
-
module Behavior
|
8
|
-
# Silences asset requests from being logged.
|
9
|
-
#
|
10
|
-
module Silencing
|
11
|
-
extend Support::Extension
|
12
|
-
|
13
|
-
apply_extension do
|
14
|
-
on "load" do
|
15
|
-
unless config.realtime.log_initial_request
|
16
|
-
Pakyow.silence do |connection|
|
17
|
-
connection.path.start_with?(File.join("/", config.realtime.path))
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "pakyow/realtime/channel"
|
4
|
-
|
5
|
-
module Pakyow
|
6
|
-
module Realtime
|
7
|
-
module Helpers
|
8
|
-
module Subscriptions
|
9
|
-
def subscribe(channel, *qualifiers)
|
10
|
-
channels = if qualifiers.empty?
|
11
|
-
Channel.new(channel)
|
12
|
-
else
|
13
|
-
qualifiers.map { |qualifier|
|
14
|
-
Channel.new(channel, qualifier)
|
15
|
-
}
|
16
|
-
end
|
17
|
-
|
18
|
-
app.websocket_server.socket_subscribe(socket_client_id, *channels)
|
19
|
-
end
|
20
|
-
|
21
|
-
def unsubscribe(channel, *qualifiers)
|
22
|
-
channels = if qualifiers.empty?
|
23
|
-
Channel.new(channel, "*")
|
24
|
-
else
|
25
|
-
qualifiers.map { |qualifier|
|
26
|
-
Channel.new(channel, qualifier)
|
27
|
-
}
|
28
|
-
end
|
29
|
-
|
30
|
-
app.websocket_server.socket_unsubscribe(*channels)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|