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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a1b20609fe040deaf1a3f8542d56b8aa94be98e09234ab8e64619cb09b45e48a
4
- data.tar.gz: cbf99d8a42dcd1777b82a26e87d6fe73a6a097a99da45e28aac476a234ccfd47
3
+ metadata.gz: b293bc25cc1b570e275cde636777adebc00bb11d18747757cc55ba39bd7da70e
4
+ data.tar.gz: 4df355cd9e243be0b9a6c4d4beb3e76c357b5d3fd9c6a5beacc4f3872ef963db
5
5
  SHA512:
6
- metadata.gz: a012079fd54b2717ded458ceb69398179dc9a88c479fb6fc39270568eb5322b232236cb3bb37e54be9cfd3521cea255735cb0c63141062dbc40e24bf9a775414
7
- data.tar.gz: f84c33e0b45c90ed0c8b9b918cb24b71650b2786c166bb3944608cb30efbfdf4bf9d185b38b0daace5a3873c62840c5021a568a26eadafaefc0f66105a051d73
6
+ metadata.gz: 55b9af0a648366f7a83a1b1294718e8ec9c6b54641f8f93aa735dcfba04ddc91d18f4fce1b363730b50d03caadbec3ec82027d3556650d93894a8b6fc20f1415
7
+ data.tar.gz: 2e91d53ec05f65673f35cdfa165a65a67756021a45817ccc8c6b45e009e794d289e7d08a5132bf875c20b60834d87945c988f7396cd795cf523534d343854659
@@ -1,29 +1,5 @@
1
- # 1.0.0
1
+ # UNRELEASED
2
2
 
3
- * IMPROVED WebSocket reliability and performance.
4
- * CHANGED WebSocket log level to verbose.
3
+ # 1.0
5
4
 
6
- # 0.11.0
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
@@ -3,9 +3,9 @@
3
3
  require "pakyow/support/extension"
4
4
 
5
5
  module Pakyow
6
- module Realtime
7
- module Behavior
8
- module Config
6
+ class Application
7
+ module Config
8
+ module Realtime
9
9
  extend Support::Extension
10
10
 
11
11
  apply_extension do
@@ -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,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pakyow
4
+ class Application
5
+ module Helpers
6
+ module Realtime
7
+ module Socket
8
+ def socket_client_id
9
+ @connection.get(:__socket_client_id)
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
@@ -6,10 +6,10 @@ require "pakyow/presenter"
6
6
 
7
7
  require "pakyow/realtime/framework"
8
8
 
9
- require "pakyow/environment/realtime/config"
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 Environment::Realtime::Config
14
+ include Config::Realtime
15
15
  end
@@ -2,37 +2,37 @@
2
2
 
3
3
  require "pakyow/framework"
4
4
 
5
- require "pakyow/realtime/helpers/broadcasting"
6
- require "pakyow/realtime/helpers/subscriptions"
7
- require "pakyow/realtime/helpers/socket"
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/realtime/behavior/config"
10
- require "pakyow/realtime/behavior/serialization"
11
- require "pakyow/realtime/behavior/server"
12
- require "pakyow/realtime/behavior/silencing"
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/realtime/behavior/rendering/install_websocket"
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 Behavior::Config
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::Rendering::InstallWebsocket
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.debug "[Pakyow::Realtime::Server::Adapters::Redis] Cleaning up channel keys"
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.debug "[Pakyow::Realtime::Server::Adapters::Redis] Removed #{removed_count} keys"
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::App
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.rc5
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-15 00:00:00.000000000 Z
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.rc5
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.rc5
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.rc5
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.rc5
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.rc5
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.rc5
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.rc5
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.rc5
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@metabahn.com
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/environment/realtime/config.rb
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.org
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: 1.3.1
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,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Pakyow
4
- module Realtime
5
- module Helpers
6
- module Broadcasting
7
- def broadcast(message)
8
- app.websocket_server.subscription_broadcast(socket_client_id, message)
9
- end
10
- end
11
- end
12
- end
13
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Pakyow
4
- module Realtime
5
- module Helpers
6
- module Socket
7
- def socket_client_id
8
- @connection.get(:__socket_client_id)
9
- end
10
- end
11
- end
12
- end
13
- 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