pakyow-realtime 1.0.0.rc5 → 1.0.0
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/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
|