I use laravel-websocket for get my user online/offline status.
This is my onClose function code in WebSocketHandler.php
file:
public function onClose(ConnectionInterface $connection)
{
$allChannels = $this->channelManager->getChannels($connection->app->id);
foreach ($allChannels as $channelData) {
$data = $channelData;
}
dd($data);
$this->channelManager->removeFromAllChannels($connection);
DashboardLogger::disconnection($connection);
StatisticsLogger::disconnection($connection);
}
And when the user closes the tab or browser my onClose function gives me $data
in console logging which is this response:
BeyondCode\LaravelWebSockets\WebSockets\Channels\PresenceChannel {#719
#users: array:1 [
1 => array:9 [
"id" => 1
"email" => "sd@sd.com"
"username" => "BlackHill"
"type" => 0
"steam_id" => "76561198107211703"
"stay_login" => 0
"email_verified_at" => null
"created_at" => "2022-03-21T22:54:53.000000Z"
"updated_at" => "2022-04-23T20:13:19.000000Z"
]
]
#sockets: array:1 [
"161595151.817952840" => "1"
]
#channelName: "presence-users"
#subscribedConnections: array:1 [
"161595151.817952840" => BeyondCode\LaravelWebSockets\Server\Logger\ConnectionLogger {#722
#connection: Ratchet\WebSocket\WsConnection {#703
#wrappedConn: Ratchet\Server\IoConnection {#691
#conn: React\Socket\Connection {#650
+unix: false
+encryptionEnabled: false
+stream: stream resource {@698
timed_out: false
blocked: false
eof: false
stream_type: "tcp_socket/ssl"
mode: "r+"
unread_bytes: 0
seekable: false
options: array:1 [
"socket" => array:1 [
"backlog" => 511
]
]
}
-input: React\Stream\DuplexResourceStream {#681
-stream: stream resource @698
-loop: React\EventLoop\StreamSelectLoop {#449
-futureTickQueue: React\EventLoop\Tick\FutureTickQueue {#450
-queue: SplQueue {#451
-flags: 4
-dllist: []
mode: IT_MODE_FIFO | IT_MODE_KEEP
dllist: []
}
}
-timers: React\EventLoop\Timer\Timers {#452
-time: 1889837.7109229
-timers: array:2 [
"000000003696a05d00000000377ed389" => React\EventLoop\Timer\Timer {#620
-interval: 60.0
-callback: Closure() {#619
class: "BeyondCode\LaravelWebSockets\Console\StartWebSocketServer"
this: BeyondCode\LaravelWebSockets\Console\StartWebSocketServer {#443 …}
}
-periodic: true
}
"000000003696a04000000000377ed389" => React\EventLoop\Timer\Timer {#625
-interval: 10.0
-callback: Closure() {#624
class: "BeyondCode\LaravelWebSockets\Console\StartWebSocketServer"
this: BeyondCode\LaravelWebSockets\Console\StartWebSocketServer {#443 …}
}
-periodic: true
}
]
-schedule: array:2 [
"000000003696a04000000000377ed389" => 1889838.6927814
"000000003696a05d00000000377ed389" => 1889888.6920111
]
-sorted: true
-useHighResolution: true
}
-readStreams: array:1 [
683 => stream resource {@683
timed_out: false
blocked: false
eof: false
stream_type: "tcp_socket/ssl"
mode: "r+"
unread_bytes: 0
seekable: false
options: array:1 [
"socket" => array:1 [
"backlog" => 511
]
]
}
]
-readListeners: array:1 [
683 => Closure($master) {#669
class: "React\Socket\TcpServer"
this: React\Socket\TcpServer {#668 …}
use: {
$that: React\Socket\TcpServer {#668 …}
}
}
]
-writeStreams: []
-writeListeners: []
-running: true
-pcntl: false
-pcntlPoll: false
-signals: React\EventLoop\SignalsHandler {#453
-signals: []
}
}
-bufferSize: 65536
-buffer: React\Stream\WritableResourceStream {#682
-stream: stream resource @698
-loop: React\EventLoop\StreamSelectLoop {#449}
-softLimit: 65536
-writeChunkSize: -1
-listening: false
-writable: false
-closed: true
-data: ""
#listeners: array:3 [
"error" => array:1 [
0 => Closure($error) {#683
class: "React\Stream\DuplexResourceStream"
this: React\Stream\DuplexResourceStream {#681}
use: {
$that: React\Stream\DuplexResourceStream {#681}
}
}
]
"close" => array:1 [
0 => array:2 [
0 => React\Stream\DuplexResourceStream {#681}
1 => "close"
]
]
"drain" => array:1 [
0 => Closure() {#684
class: "React\Stream\DuplexResourceStream"
this: React\Stream\DuplexResourceStream {#681}
use: {
$that: React\Stream\DuplexResourceStream {#681}
}
}
]
]
#onceListeners: []
}
-readable: false
-writable: false
-closing: false
-listening: false
#listeners: array:6 [
"data" => array:1 [
0 => Closure() {#685
class: "React\Stream\Util"
use: {
$event: "data"
$target: React\Socket\Connection {#650}
}
}
]
"end" => array:1 [
0 => Closure() {#686
class: "React\Stream\Util"
use: {
$event: "end"
$target: React\Socket\Connection {#650}
}
}
]
"error" => array:1 [
0 => Closure() {#687
class: "React\Stream\Util"
use: {
$event: "error"
$target: React\Socket\Connection {#650}
}
}
]
"close" => array:2 [
0 => Closure() {#688
class: "React\Stream\Util"
use: {
$event: "close"
$target: React\Socket\Connection {#650}
}
}
1 => array:2 [
0 => React\Socket\Connection {#650}
1 => "close"
]
]
"pipe" => array:1 [
0 => Closure() {#689
class: "React\Stream\Util"
use: {
$event: "pipe"
$target: React\Socket\Connection {#650}
}
}
]
"drain" => array:1 [
0 => Closure() {#690
class: "React\Stream\Util"
use: {
$event: "drain"
$target: React\Socket\Connection {#650}
}
}
]
]
#onceListeners: []
}
#listeners: array:3 [
"data" => array:1 [
0 => Closure($data) {#692
class: "Ratchet\Server\IoServer"
this: Ratchet\Server\IoServer {#680 …}
use: {
$conn: React\Socket\Connection {#650}
}
}
]
"close" => array:1 [
0 => Closure() {#693
class: "Ratchet\Server\IoServer"
this: Ratchet\Server\IoServer {#680 …}
use: {
$conn: React\Socket\Connection {#650}
}
}
]
"error" => array:1 [
0 => Closure(Exception $e) {#694
class: "Ratchet\Server\IoServer"
this: Ratchet\Server\IoServer {#680 …}
use: {
$conn: React\Socket\Connection {#650}
}
}
]
]
#onceListeners: []
+"decor": Ratchet\Server\IoConnection {#691}
}
+"resourceId": 698
+"remoteAddress": "127.0.0.1"
+"httpHeadersReceived": true
+"controller": Ratchet\WebSocket\WsServer {#626
-delegate: BeyondCode\LaravelWebSockets\Server\Logger\WebsocketsLogger {#627
#app: BeyondCode\LaravelWebSockets\WebSockets\WebSocketHandler {#629
#channelManager: BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManagers\ArrayChannelManager {#630
#appId: null
#channels: array:1 [
"local" => array:1 [
"presence-users" => BeyondCode\LaravelWebSockets\WebSockets\Channels\PresenceChannel {#719}
]
]
}
}
#consoleOutput: Illuminate\Console\OutputStyle {#599
-output: Symfony\Component\Console\Output\ConsoleOutput {#24
-stderr: Symfony\Component\Console\Output\StreamOutput {#42
-stream: stream resource {@3
timed_out: false
blocked: true
eof: false
wrapper_type: "PHP"
stream_type: "STDIO"
mode: "wb"
unread_bytes: 0
seekable: false
uri: "php://stderr"
options: []
}
-verbosity: 32
-formatter: Symfony\Component\Console\Formatter\OutputFormatter {#43
-decorated: true
-styles: array:4 [
"error" => Symfony\Component\Console\Formatter\OutputFormatterStyle {#44
-color: Symfony\Component\Console\Color {#45
-foreground: "37"
-background: "41"
-options: []
}
-foreground: "white"
-background: "red"
-options: []
-href: null
}
"info" => Symfony\Component\Console\Formatter\OutputFormatterStyle {#46
-color: Symfony\Component\Console\Color {#47
-foreground: "32"
-background: ""
-options: []
}
-foreground: "green"
-background: ""
-options: []
-href: null
}
"comment" => Symfony\Component\Console\Formatter\OutputFormatterStyle {#48
-color: Symfony\Component\Console\Color {#49
-foreground: "33"
-background: ""
-options: []
}
-foreground: "yellow"
-background: ""
-options: []
-href: null
}
"question" => Symfony\Component\Console\Formatter\OutputFormatterStyle {#50
-color: Symfony\Component\Console\Color {#51
-foreground: "30"
-background: "46"
-options: []
}
-foreground: "black"
-background: "cyan"
-options: []
-href: null
}
]
-styleStack: Symfony\Component\Console\Formatter\OutputFormatterStyleStack {#52
-styles: []
-emptyStyle: Symfony\Component\Console\Formatter\OutputFormatterStyle {#53
-color: Symfony\Component\Console\Color {#54
-foreground: ""
-background: ""
-options: []
}
-foreground: ""
-background: ""
-options: []
-href: null
}
}
}
}
-consoleSectionOutputs: []
-stream: stream resource {@2
timed_out: false
blocked: true
eof: false
wrapper_type: "PHP"
stream_type: "STDIO"
mode: "wb"
unread_bytes: 0
seekable: false
uri: "php://stdout"
options: []
}
-verbosity: 32
-formatter: Symfony\Component\Console\Formatter\OutputFormatter {#23
-decorated: true
-styles: array:5 [
"error" => Symfony\Component\Console\Formatter\OutputFormatterStyle {#31
-color: Symfony\Component\Console\Color {#32
-foreground: "37"
-background: "41"
-options: []
}
-foreground: "white"
-background: "red"
-options: []
-href: null
}
"info" => Symfony\Component\Console\Formatter\OutputFormatterStyle {#33
-color: Symfony\Component\Console\Color {#34
-foreground: "32"
-background: ""
-options: []
}
-foreground: "green"
-background: ""
-options: []
-href: null
-handlesHrefGracefully: false
}
"comment" => Symfony\Component\Console\Formatter\OutputFormatterStyle {#35
-color: Symfony\Component\Console\Color {#36
-foreground: "33"
-background: ""
-options: []
}
-foreground: "yellow"
-background: ""
-options: []
-href: null
}
"question" => Symfony\Component\Console\Formatter\OutputFormatterStyle {#37
-color: Symfony\Component\Console\Color {#38
-foreground: "30"
-background: "46"
-options: []
}
-foreground: "black"
-background: "cyan"
-options: []
-href: null
}
"warning" => Symfony\Component\Console\Formatter\OutputFormatterStyle {#709
-color: Symfony\Component\Console\Color {#710
-foreground: "33"
-background: ""
-options: []
}
-foreground: "yellow"
-background: ""
-options: []
-href: null
-handlesHrefGracefully: false
}
]
-styleStack: Symfony\Component\Console\Formatter\OutputFormatterStyleStack {#39
-styles: []
-emptyStyle: Symfony\Component\Console\Formatter\OutputFormatterStyle {#40
-color: Symfony\Component\Console\Color {#41
-foreground: ""
-background: ""
-options: []
}
-foreground: ""
-background: ""
-options: []
-href: null
}
}
}
}
-input: Symfony\Component\Console\Input\ArgvInput {#26
-tokens: array:1 [
0 => "websockets:serve"
]
-parsed: []
#definition: Symfony\Component\Console\Input\InputDefinition {#598
-arguments: array:1 [
"command" => Symfony\Component\Console\Input\InputArgument {#588
-name: "command"
-mode: 1
-default: null
-description: "The command to execute"
}
]
-requiredCount: 1
-lastArrayArgument: null
-lastOptionalArgument: null
-options: array:10 [
"host" => Symfony\Component\Console\Input\InputOption {#445
-name: "host"
-shortcut: null
-mode: 4
-default: "0.0.0.0"
-description: ""
}
"port" => Symfony\Component\Console\Input\InputOption {#436
-name: "port"
-shortcut: null
-mode: 4
-default: "6001"
-description: ""
}
"debug" => Symfony\Component\Console\Input\InputOption {#447
-name: "debug"
-shortcut: null
-mode: 1
-default: false
-description: "Forces the loggers to be enabled and thereby overriding the app.debug config setting"
}
"help" => Symfony\Component\Console\Input\InputOption {#589
-name: "help"
-shortcut: "h"
-mode: 1
-default: false
-description: "Display help for the given command. When no command is given display help for the <info>list</info> command"
}
"quiet" => Symfony\Component\Console\Input\InputOption {#590
-name: "quiet"
-shortcut: "q"
-mode: 1
-default: false
-description: "Do not output any message"
}
"verbose" => Symfony\Component\Console\Input\InputOption {#591
-name: "verbose"
-shortcut: "v|vv|vvv"
-mode: 1
-default: false
-description: "Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug"
}
"version" => Symfony\Component\Console\Input\InputOption {#592
-name: "version"
-shortcut: "V"
-mode: 1
-default: false
-description: "Display this application version"
}
"ansi" => Symfony\Component\Console\Input\InputOption {#593
-name: "ansi"
-shortcut: null
-mode: 16
-default: null
-description: "Force (or disable --no-ansi) ANSI output"
}
"no-interaction" => Symfony\Component\Console\Input\InputOption {#594
-name: "no-interaction"
-shortcut: "n"
-mode: 1
-default: false
-description: "Do not ask any interactive question"
}
"env" => Symfony\Component\Console\Input\InputOption {#596
-name: "env"
-shortcut: null
-mode: 4
-default: null
-description: "The environment the command should run under"
}
]
-negations: array:1 [
"no-ansi" => "ansi"
]
-shortcuts: array:7 [
"h" => "help"
"q" => "quiet"
"v" => "verbose"
"vv" => "verbose"
"vvv" => "verbose"
"V" => "version"
"n" => "no-interaction"
]
}
#stream: null
#options: []
#arguments: array:1 [
"command" => "websockets:serve"
]
#interactive: true
}
-questionHelper: null
-progressBar: null
-lineLength: 120
-bufferedOutput: Symfony\Component\Console\Output\TrimmedBufferOutput {#600
-maxLength: 4
-buffer: "g>\r\n"
-verbosity: 32
-formatter: Symfony\Component\Console\Formatter\OutputFormatter {#601
-decorated: false
-styles: array:4 [
"error" => Symfony\Component\Console\Formatter\OutputFormatterStyle {#603
-color: Symfony\Component\Console\Color {#32}
-foreground: "white"
-background: "red"
-options: []
-href: null
}
"info" => Symfony\Component\Console\Formatter\OutputFormatterStyle {#604
-color: Symfony\Component\Console\Color {#34}
-foreground: "green"
-background: ""
-options: []
-href: null
-handlesHrefGracefully: false
}
"comment" => Symfony\Component\Console\Formatter\OutputFormatterStyle {#605
-color: Symfony\Component\Console\Color {#36}
-foreground: "yellow"
-background: ""
-options: []
-href: null
}
"question" => Symfony\Component\Console\Formatter\OutputFormatterStyle {#606
-color: Symfony\Component\Console\Color {#38}
-foreground: "black"
-background: "cyan"
-options: []
-href: null
}
]
-styleStack: Symfony\Component\Console\Formatter\OutputFormatterStyleStack {#602
-styles: []
-emptyStyle: Symfony\Component\Console\Formatter\OutputFormatterStyle {#40}
}
}
}
-output: Symfony\Component\Console\Output\ConsoleOutput {#24}
-output: Symfony\Component\Console\Output\ConsoleOutput {#24}
}
#enabled: true
#verbose: false
}
#connections: SplObjectStorage {#632
storage: []
}
-closeFrameChecker: Ratchet\RFC6455\Messaging\CloseFrameChecker {#633
-validCloseCodes: array:9 [
0 => 1000
1 => 1001
2 => 1002
3 => 1003
4 => 1007
5 => 1008
6 => 1009
7 => 1010
8 => 1011
]
}
-handshakeNegotiator: Ratchet\RFC6455\Handshake\ServerNegotiator {#634
-verifier: Ratchet\RFC6455\Handshake\RequestVerifier {#635}
-_supportedSubProtocols: []
-_strictSubProtocols: true
-enablePerMessageDeflate: false
}
-ueFlowFactory: Closure() {#638
class: "Ratchet\WebSocket\WsServer"
this: Ratchet\WebSocket\WsServer {#626}
use: {
$reusableUnderflowException: UnderflowException {#637 …}
}
}
-pongReceiver: Closure() {#636
class: "Ratchet\WebSocket\WsServer"
this: Ratchet\WebSocket\WsServer {#626}
}
-msgCb: Closure(ConnectionInterface $conn, MessageInterface $msg) {#631
class: "Ratchet\WebSocket\WsServer"
this: Ratchet\WebSocket\WsServer {#626}
}
}
+"httpRequest": GuzzleHttp\Psr7\Request {#697
-method: "GET"
-requestTarget: null
-uri: GuzzleHttp\Psr7\Uri {#698
-scheme: "http"
-userInfo: ""
-host: "localhost"
-port: 6001
-path: "/app/local"
-query: "appKey=local&protocol=7&client=js&version=7.0.6&flash=false"
-fragment: ""
-composedComponents: null
}
+"socketId": "161595151.817952840"
}
}
#consoleOutput: Illuminate\Console\OutputStyle {#599}
#enabled: true
#verbose: false
}
]
}
I need to access #users
array to apply changes to any user who leaves.
In this issue they managed to get channelName but I did not get #users using their solution!