php namespace ZF Net XMPP use ZF Config use ZF Net XMPP class GCM priv

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<?php
namespace ZF\Net\XMPP;
use \ZF\Config;
use \ZF\Net\XMPP;
class GCM {
private $s, $mainstream_id;
private $auth_data = array();
private $google_close_connection = false;
private $config;
public function __construct($config = NULL) {
$this->config = $config ? $config : Config::get("gcm");
$this->s = new XMPP\XML\Stream(array(
"server" => $this->config['server'],
"port" => $this->config['port'],
"secure" => XMPP\XML\Stream::SECURE_TLS
));
}
public function connect() {
// Подключаемся
$tries = 30;
while (!$this->s->connect() && $tries)
--$tries;
if (!$this->s->isConnected())
throw new XMPP\Exception("Can't connect: ".$this->s->error);
// Начинаем стрим
$this->s->startStream();
if (!$this->auth($this->config['login'], $this->config['password'], $this->config['xmpp_resource']))
throw new XMPP\GCM\Exception("Authorization failed!");
}
public function auth($user, $password, $resource) {
$this->auth_data = func_get_args();
$this->s->send('<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="PLAIN">'
.base64_encode("\0".$user."\0".$password).'</auth>');
$tag = $this->s->recv();
$is_ok =
$tag &&
$tag->name == "SUCCESS" &&
$this->s->startStream() &&
$this->bindResource($resource);
if ($is_ok)
$this->mainstream_id = $this->s->getStreamID();
return $is_ok;
}
public function bindResource($res) {
if (!$this->s->send("<iq type='set'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><resource>".htmlspecialchars($res, ENT_QUOTES)."</resource></bind></iq>"))
return false;
if (!($data = $this->s->recv()) || !$data->findByName("jid"))
return false;
return true;
}
public function sendMessage($msg, $check_status = true) {
$this->checkConnection();
if ($this->s->send('<message id=""><gcm xmlns="google:mobile:data">'.htmlspecialchars(json_encode($msg), ENT_QUOTES).'</gcm></message>')) {
if (!$check_status)
return $this;
while ($data = $this->s->recv()) {
if ($data->name != 'MESSAGE')
continue;
if ($data->attr('type') == 'error') {
$text = $data->findByName('text');
if ($text) {
throw new XMPP\GCM\Exception("Stanza error: ".$text[0]->value);
} else
throw new XMPP\GCM\Exception("Unknown stanza error: ".$data);
}
$gcm_data = $data->findByNS("google:mobile:data");
if ($gcm_data) {
$json = json_decode($gcm_data[0]->value, true);
if (!$json || !isset($json['message_type']))
throw new XMPP\GCM\Exception("Json parse error: ".$gcm_data[0]->value);
if ($json['message_type'] == 'ack') {
// ok, успешно отправлено
return $this;
} elseif ($json['message_type'] == 'control') {
$this->google_close_connection = true;
continue;
} else {
throw new XMPP\GCM\Exception("GCM error (".$json['error']."): ".$json['error_description']);
}
} else
throw new XMPP\GCM\Exception("GCM data not found: ".$data);
}
}
return $this->sendMessage($msg);
}
public function isAuthed() {
return $this->s->getStreamID() == $this->mainstream_id;
}
public function isConnected() {
return $this->s->getStreamID() > 0 && $this->s->isConnected();
}
public function checkConnection() {
if (!$this->isConnected() || !$this->isAuthed()) {
$this->connect();
return true;
} elseif ($this->google_close_connection) {
$this->google_close_connection = false;
$this->close();
}
return false;
}
public function waitMessage() {
while ($data = $this->s->recv()) {
if ($data->name == "MESSAGE")
return $data;
}
return NULL;
}
public function close() {
if ($this->isConnected())
$this->s->endStream();
$this->s->close();
}
}