Closed sauerbraten closed 1 year ago
Is it possible to split these into two separate PRs? One for the session support and one for the replicator stuff?
Sure, let's start with this!
Given this is such an old issue, we've decided to close this. If you still need this, let us know and we'll definitely re-open and re-visit!
That's a shame, I would love to see this feature being part of the collaboration package.
Last time I checked this pull request was already working fine, what would you still need to include this into the package?
This PR adds ~two~ one feature:
Multiple Sessions Support
In order to sync changes between two sessions of the same user, each session must act as a separate Echo user. (Pusher does not play back events triggered by A to any of A's connections.) To pretend to Echo/Pusher that each session is a different user, we have a custom User and UserRepository class:
Laravel Echo calls getAuthIdentifierForBroadcasting() if present on the user object it sees, and we include Pusher's socket_id in the ID used for broadcasting. That way, Pusher treats all websocket connections as different members of the presence channel and broadcasts changes between all of them.
In order to access the socket ID of the author of a channel event, it's necessary to use Echo's on() method with Pusher-specific event names instead of the more abstract here(), joining() or leaving() functions Echo provides.
As a rule of thumb, if
user
is the callback argument to a 'pusher:*' event:user.id
is the Echo broadcasting ID (i.e. contains the Pusher socket ID and is unique for each websocket),user.info
is what collaboration's Broadcast::channel() callback returns (i.e. what the corresponding here()/joining()/leaving() callback would have gotten as its argument), anduser.info.id
is the Statamic user ID (i.e. is the same for every session belonging to the same Statamic user).Also, while collaboration sent the entire Statamic user object with each message before, now only the Pusher member ID (= Echo broadcasting ID) is sent, and clients resolve that ID locally in the user data they received when joining the channel.
Note: this solution works well with Pusher, but is untested and might break with any other Laravel broadcasting provider!
~Set-level locking in Replicator~
~While the core patch (https://github.com/sauerbraten/cms/commit/891bcc6fe03ea68f2f2b38e3e569b0a1d9f13cc1) has most of the magic, collaboration needs to support the new Pusher events 'focus-set' and 'blur-set' as well as the Vuex mutations 'lockReplicatorSet' and 'unlockReplicatorSet'.~