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 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