public function onMessage(WebSocketTransportInterface $user, WebSocketMessageInterface $msg) { $data = json_decode($msg->getData()); if ($data == null) { $this->say('Unparsable JSON : ' . $msg->getData()); return false; } if (!isset($data->type)) { $this->say('No type given'); return false; } if ($this->debug) { $this->say(' <- ' . $data->type); } switch ($data->type) { case 'ping': $data->type = 'pong'; $user->sendString(json_encode($data)); break; case 'pong': $user->ping = true; break; case 'register': if (isset($data->player_id) && isset($data->nick)) { $ban = $this->observer->bans->is(null, $data->player_id); if ($ban) { $this->say('Connexion attempt from banned user ' . $data->player_id . ' (' . $ban->reason . ')'); $user->sendString('{"type": "ban", "reason": "' . $ban->reason . '"}'); } else { $user->player_id = $data->player_id; $user->nick = $data->nick; $this->register_user($user, $data); } } else { $this->say('Incomplete registration : ' . $data->player_id . ' / ' . $data->nick); $user->close(); } break; default: if (isset($user->player_id)) { $this->recieve($user, $data); } else { $this->say('Action ' . $data->type . ' from unregistered user'); $user->close(); } } }
/** * Entry point for all messages received from clients in this proxy 'room' * * @param WebSocketTransportInterface $user * @param WebSocketMessageInterface $msg */ public function onMessage(WebSocketTransportInterface $user, WebSocketMessageInterface $msg) { try { $message = json_decode($msg->getData()); if ($message->command == 'connect') { $this->requestConnect($user, $message); } elseif ($message->command == 'write') { $this->requestWrite($user, $message); } elseif ($message->command == 'close') { $this->requestClose($user, $message); } } catch (Exception $e) { $this->logger->err($e->getMessage()); } }
/** * Handles incoming websocket messages, parses them, and emits them as remote events. * * @param WebSocketMessageInterface $messageRaw A websocket message. */ private function onMessage(WebSocketMessageInterface $message) { // parse the message and get the event name $payload = Payload::fromJson($message->getData()); if (isset($payload['type'])) { switch ($payload['type']) { case 'hello': $this->connected = true; break; case 'team_rename': $this->team->data['name'] = $payload['name']; break; case 'team_domain_change': $this->team->data['domain'] = $payload['domain']; break; case 'channel_created': $this->getChannelById($payload['channel']['id'])->then(function (Channel $channel) { $this->channels[$channel->getId()] = $channel; }); break; case 'channel_deleted': unset($this->channels[$payload['channel']['id']]); break; case 'channel_rename': $this->channels[$payload['channel']['id']]->data['name'] = $payload['channel']['name']; break; case 'channel_archive': $this->channels[$payload['channel']['id']]->data['is_archived'] = true; break; case 'channel_unarchive': $this->channels[$payload['channel']['id']]->data['is_archived'] = false; break; case 'group_joined': $group = new Group($this, $payload['channel']); $this->groups[$group->getId()] = $group; break; case 'group_rename': $this->groups[$payload['group']['id']]->data['name'] = $payload['channel']['name']; break; case 'group_archive': $this->groups[$payload['group']['id']]->data['is_archived'] = true; break; case 'group_unarchive': $this->groups[$payload['group']['id']]->data['is_archived'] = false; break; case 'im_created': $dm = new DirectMessageChannel($this, $payload['channel']); $this->dms[$dm->getId()] = $dm; break; } // emit an event with the attached json $this->emit($payload['type'], [$payload]); } else { // If reply_to is set, then it is a server confirmation for a previously // sent message if (isset($payload['reply_to'])) { if (isset($this->pendingMessages[$payload['reply_to']])) { $deferred = $this->pendingMessages[$payload['reply_to']]; // Resolve or reject the promise that was waiting for the reply. if (isset($payload['ok']) && $payload['ok'] === true) { $deferred->resolve(); } else { $deferred->reject($payload['error']); } unset($this->pendingMessages[$payload['reply_to']]); } } } }
public function onMessage(WebSocketTransportInterface $user, WebSocketMessageInterface $msg) { //do nothing $this->logger->notice("Client is talking to the wind. ({$msg->getData()}, {$user->getId()})"); }
public function onMessage(WebSocketTransportInterface $user, WebSocketMessageInterface $msg) { //do nothing $this->logger->notice("User {$user->getId()} is not in a room but tried to say: {$msg->getData()}"); }
/** * Handle a message from a client. * * @param WebSocketTransportInterface $user * @param WebSocketMessageInterface $msg */ public function onMessage(WebSocketTransportInterface $user, WebSocketMessageInterface $msg) { $data = json_decode($msg->getData(), true); if (!$data['action'] || !in_array($data['action'], ['subscribe', 'unsubscribe', 'publish'])) { return; } switch ($data['action']) { case 'subscribe': case 'unsubscribe': if (isset($data['query'])) { $args = json_decode($data['query'], true); $count = count($args); if ($count > 1) { for ($i = 1; $i < $count; $i++) { $newArg = \Nymph\REST::translateSelector($args[$i]); if ($newArg === false) { return; } $args[$i] = $newArg; } } if (count($args) > 1) { $options = $args[0]; unset($args[0]); \Nymph\Nymph::formatSelectors($args); $args = array_merge([$options], $args); } $args[0]['skip_ac'] = true; $serialArgs = serialize($args); if ($data['action'] === 'subscribe') { if (!key_exists($serialArgs, $this->subscriptions['queries'])) { $guidArgs = $args; $guidArgs[0]['return'] = 'guid'; $this->subscriptions['queries'][$serialArgs] = ['current' => call_user_func_array("\\Nymph\\Nymph::getEntities", $guidArgs)]; } $this->subscriptions['queries'][$serialArgs][] = ['client' => $user, 'query' => $data['query'], 'count' => !!$data['count']]; $this->logger->notice("Client subscribed to a query! ({$serialArgs}, {$user->getId()})"); if (RequirePHP::_('NymphPubSubConfig')['broadcast_counts']) { // Notify clients of the subscription count. $count = count($this->subscriptions['queries'][$serialArgs]) - 1; foreach ($this->subscriptions['queries'][$serialArgs] as $key => $curClient) { if ($key === 'current') { continue; } if ($curClient['count']) { $curClient['client']->sendString(json_encode(['query' => $curClient['query'], 'count' => $count])); } } } } elseif ($data['action'] === 'unsubscribe') { if (!key_exists($serialArgs, $this->subscriptions['queries'])) { return; } foreach ($this->subscriptions['queries'][$serialArgs] as $key => $value) { if ($key === 'current') { continue; } if ($user->getId() === $value['client']->getId() && $data['query'] === $value['query']) { unset($this->subscriptions['queries'][$serialArgs][$key]); $this->logger->notice("Client unsubscribed from a query! ({$serialArgs}, {$user->getId()})"); if (RequirePHP::_('NymphPubSubConfig')['broadcast_counts']) { // Notify clients of the subscription count. $count = count($this->subscriptions['queries'][$serialArgs]) - 1; foreach ($this->subscriptions['queries'][$serialArgs] as $key => $curClient) { if ($key === 'current') { continue; } if ($curClient['count']) { $curClient['client']->sendString(json_encode(['query' => $curClient['query'], 'count' => $count])); } } } if (count($this->subscriptions['queries'][$serialArgs]) === 1) { unset($this->subscriptions['queries'][$serialArgs]); } } } } } elseif (isset($data['uid']) && is_string($data['uid'])) { if ($data['action'] === 'subscribe') { if (!key_exists($data['uid'], $this->subscriptions['uids'])) { $this->subscriptions['uids'][$data['uid']] = []; } $this->subscriptions['uids'][$data['uid']][] = ['client' => $user, 'count' => !!$data['count']]; $this->logger->notice("Client subscribed to a UID! ({$data['uid']}, {$user->getId()})"); if (RequirePHP::_('NymphPubSubConfig')['broadcast_counts']) { // Notify clients of the subscription count. $count = count($this->subscriptions['uids'][$data['uid']]); foreach ($this->subscriptions['uids'][$data['uid']] as $curClient) { if ($curClient['count']) { $curClient['client']->sendString(json_encode(['uid' => $data['uid'], 'count' => $count])); } } } } elseif ($data['action'] === 'unsubscribe') { if (!key_exists($data['uid'], $this->subscriptions['uids'])) { return; } foreach ($this->subscriptions['uids'][$data['uid']] as $key => $value) { if ($user->getId() === $value['client']->getId()) { unset($this->subscriptions['uids'][$data['uid']][$key]); $this->logger->notice("Client unsubscribed from a UID! ({$data['uid']}, {$user->getId()})"); if (RequirePHP::_('NymphPubSubConfig')['broadcast_counts']) { // Notify clients of the subscription count. $count = count($this->subscriptions['uids'][$data['uid']]); foreach ($this->subscriptions['uids'][$data['uid']] as $curClient) { if ($curClient['count']) { $curClient['client']->sendString(json_encode(['uid' => $data['uid'], 'count' => $count])); } } } break; } } if (count($this->subscriptions['uids'][$data['uid']]) === 0) { unset($this->subscriptions['uids'][$data['uid']]); } } } break; case 'publish': if (isset($data['guid']) && ($data['event'] === 'delete' || isset($data['entity']) && ($data['event'] === 'create' || $data['event'] === 'update'))) { $this->logger->notice("Received an entity publish! ({$data['guid']}, {$data['event']}, {$user->getId()})"); // Relay the publish to other servers. $this->relay($msg->getData()); foreach ($this->subscriptions['queries'] as $curQuery => &$curClients) { if ($data['event'] === 'delete' || $data['event'] === 'update') { // Check if it is in any queries' currents. if (in_array($data['guid'], $curClients['current'])) { // Update currents list. $guidArgs = unserialize($curQuery); $guidArgs[0]['return'] = 'guid'; $curClients['current'] = call_user_func_array("\\Nymph\\Nymph::getEntities", $guidArgs); // Notify subscribers. foreach ($curClients as $key => $curClient) { if ($key === 'current') { continue; } $this->logger->notice("Notifying client of modification! ({$curClient['client']->getId()})"); $curClient['client']->sendString(json_encode(['query' => $curClient['query']])); } continue; } } // It isn't in the current matching entities. if ($data['event'] === 'create' || $data['event'] === 'update') { // Check if it matches any queries. $selectors = unserialize($curQuery); $options = $selectors[0]; unset($selectors[0]); $entityData = $data['entity']['data']; $entityData['cdate'] = $data['entity']['cdate']; $entityData['mdate'] = $data['entity']['mdate']; $entitySData = []; if ($options['class'] === $data['entity']['class'] && \Nymph\Nymph::checkData($entityData, $entitySData, $selectors, $data['guid'], $data['entity']['tags'])) { // Update currents list. $guidArgs = unserialize($curQuery); $guidArgs[0]['return'] = 'guid'; $curClients['current'] = call_user_func_array("\\Nymph\\Nymph::getEntities", $guidArgs); // If we're here, it means the query didn't // match the entity before, and now it does. We // could check currents to see if it's been // removed by limits, but that may give us bad // data, since the client queries are filtered // by Tilmeld. // Notify subscribers. foreach ($curClients as $key => $curClient) { if ($key === 'current') { continue; } $this->logger->notice("Notifying client of new match! ({$curClient['client']->getId()})"); $curClient['client']->sendString(json_encode(['query' => $curClient['query']])); } } } } unset($curClients); } elseif ((isset($data['name']) || isset($data['oldName']) && isset($data['newName'])) && in_array($data['event'], ['newUID', 'setUID', 'renameUID', 'deleteUID'])) { $this->logger->notice("Received a UID publish! (" . (isset($data['name']) ? $data['name'] : "{$data['oldName']} => {$data['newName']}") . ", {$data['event']}, {$user->getId()})"); // Relay the publish to other servers. $this->relay($msg->getData()); foreach ($data as $key => $name) { if (!in_array($key, ['name', 'newName', 'oldName']) || !key_exists($name, $this->subscriptions['uids'])) { continue; } foreach ($this->subscriptions['uids'][$name] as $curClient) { $this->logger->notice("Notifying client of {$data['event']}! ({$name}, {$curClient['client']->getId()})"); $curClient['client']->sendString(json_encode(['uid' => $name])); } } } break; } }