}\r
}\r
\r
+ /**\r
+ * Message pump is triggered on socket input, so we only need an idle()\r
+ * call often enough to trigger our outgoing pings.\r
+ */\r
+ function timeout() {\r
+ return $this->pingInterval;\r
+ }\r
+\r
/**\r
* Process MSN events that have come in over the wire.\r
*\r
*\r
* @return void\r
*/\r
- function connect() {\r
+ public function connect() {\r
if (!$this->conn) {\r
$this->conn = new MSN(\r
array(\r
'debug' => true\r
)\r
);\r
- $this->conn->registerHandler("IMIn", array($this, 'handle_msn_message'));\r
+ $this->conn->registerHandler('IMin', array($this, 'handle_msn_message'));\r
+ $this->conn->registerHandler('SessionReady', array($this, 'handle_session_ready'));\r
$this->conn->registerHandler('Pong', array($this, 'update_ping_time'));\r
$this->conn->registerHandler('ConnectFailed', array($this, 'handle_connect_failed'));\r
$this->conn->registerHandler('Reconnect', array($this, 'handle_reconnect'));\r
\r
/**\r
* Update the time till the next ping\r
+ *\r
* @param $data Time till next ping\r
+ * @return void\r
*/\r
- private function update_ping_time($data) {\r
- $pingInterval = $data;\r
+ public function update_ping_time($data) {\r
+ $this->pingInterval = $data;\r
}\r
\r
/**\r
* Passes it back to the queuing system\r
*\r
* @param array $data Data\r
- * @return void\r
+ * @return boolean\r
*/\r
- private function handle_msn_message($data) {\r
+ public function handle_msn_message($data) {\r
$this->plugin->enqueue_incoming_raw($data);\r
return true;\r
}\r
\r
+ /**\r
+ * Called via a callback when a session becomes ready\r
+ *\r
+ * @param array $data Data\r
+ */\r
+ public function handle_session_ready($data) {\r
+ $sessionFailed = false;\r
+ $wm = Msn_waiting_message::top($data['to']);\r
+ while ($wm != NULL) {\r
+ if ($sessionFailed) {\r
+ $this->plugin->send_message($wm->screenname, $wm->message);\r
+ $sessionFailed = true;\r
+ } elseif (!$this->conn->sendMessage($wm->screenname, $wm->message, $ignore)) {\r
+ $this->plugin->send_message($wm->screenname, $wm->message);\r
+ }\r
+\r
+ $wm->delete();\r
+ $wm = Msn_waiting_message::top($data['to']);\r
+ }\r
+ }\r
+\r
/**\r
* Called by callback to log failure during connect\r
*\r
* @param void $data Not used (there to keep callback happy)\r
* @return void\r
*/\r
- function handle_connect_failed($data) {\r
+ public function handle_connect_failed($data) {\r
common_log(LOG_NOTICE, 'MSN connect failed, retrying');\r
}\r
\r
* @param void $data Not used (there to keep callback happy)\r
* @return void\r
*/\r
- function handle_reconnect($data) {\r
+ public function handle_reconnect($data) {\r
common_log(LOG_NOTICE, 'MSN reconnecting');\r
}\r
\r
- function send_raw_message($data) {\r
+ /**\r
+ * Enters a message into the database for sending via a callback\r
+ * when the session is established\r
+ *\r
+ * @param string $to Intended recipient\r
+ * @param string $message Message\r
+ */\r
+ private function enqueue_waiting_message($to, $message) {\r
+ $wm = new Msn_waiting_message();\r
+\r
+ $wm->screenname = $to;\r
+ $wm->message = $message;\r
+ $wm->created = common_sql_now();\r
+ $result = $wm->insert();\r
+\r
+ if (!$result) {\r
+ common_log_db_error($wm, 'INSERT', __FILE__);\r
+ throw new ServerException('DB error inserting queue item');\r
+ }\r
+\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Send a message using the daemon\r
+ *\r
+ * @param $data Message data\r
+ * @return boolean true on success\r
+ */\r
+ public function send_raw_message($data) {\r
$this->connect();\r
if (!$this->conn) {\r
return false;\r
}\r
\r
- if (!$this->conn->sendMessage($data['to'], $data['message'])) {\r
- return false;\r
+ $waitForSession = false;\r
+ if (!$this->conn->sendMessage($data['to'], $data['message'], $waitForSession)) {\r
+ if ($waitForSession) {\r
+ $this->enqueue_waiting_message($data['to'], $data['message']);\r
+ } else {\r
+ return false;\r
+ }\r
}\r
\r
// Sending a command updates the time till next ping\r