mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 00:46:50 +02:00
Some cleanups from Jon ... beeps now work
This commit is contained in:
parent
e7a80e32c9
commit
e7d27884a8
1 changed files with 92 additions and 60 deletions
|
@ -34,28 +34,22 @@ function chat_empty_connection() {
|
|||
}
|
||||
|
||||
class ChatConnection {
|
||||
// Chat-related info
|
||||
var $sid = NULL;
|
||||
var $type = NULL;
|
||||
//var $groupid = NULL;
|
||||
|
||||
// PHP-level info
|
||||
var $handle = NULL;
|
||||
|
||||
// TCP/IP
|
||||
var $ip = NULL;
|
||||
var $port = NULL;
|
||||
var $groupid = NULL;
|
||||
var $lastmessages = array();
|
||||
var $lastmsgindex = 0;
|
||||
var $type = NULL;
|
||||
}
|
||||
|
||||
class ChatMessage {
|
||||
var $chatid = NULL;
|
||||
var $userid = NULL;
|
||||
var $groupid = NULL;
|
||||
var $system = NULL;
|
||||
var $message = NULL;
|
||||
var $timestamp = NULL;
|
||||
|
||||
var $text_ = '';
|
||||
var $html_ = '';
|
||||
var $beep_ = false;
|
||||
|
||||
function ChatConnection($resource) {
|
||||
$this->handle = $resource;
|
||||
socket_getpeername($this->handle, &$this->ip, &$this->port);
|
||||
}
|
||||
}
|
||||
|
||||
class ChatDaemon {
|
||||
|
@ -150,8 +144,9 @@ class ChatDaemon {
|
|||
echo "</a></td><td valign=center>";
|
||||
echo "<p><font size=1>";
|
||||
echo fullname($userinfo['user'])."<br />";
|
||||
echo "<font color=\"#888888\">$str->idle: ".format_time($lastping, $str)."</font>";
|
||||
//echo " <a href=\"users.php?chat_sid=$chat_sid&beep=$chatuser->id&groupid=$groupid\">$str->beep</a>";
|
||||
echo "<font color=\"#888888\">$str->idle: ".format_time($lastping, $str)."</font> ";
|
||||
echo '<a target="empty" href="http://'.$CFG->chat_serverhost.':'.$CFG->chat_serverport.'/?win=beep&beep='.$userinfo['user']->id.
|
||||
'&chat_sid='.$sessionid.'&groupid='.$this->sets_info[$sessionid]['groupid'].'">'.$str->beep."</a>\n";
|
||||
echo "</font></p>";
|
||||
echo "<td></tr>";
|
||||
}
|
||||
|
@ -178,6 +173,7 @@ class ChatDaemon {
|
|||
return true;
|
||||
}
|
||||
foreach($this->conn_side[$sessionid] as $sideid => $sidekick) {
|
||||
// TODO: is this late-dispatch working correctly?
|
||||
$this->dispatch_sidekick($sidekick['handle'], $sidekick['type'], $sessionid, $sidekick['customdata']);
|
||||
unset($this->conn_side[$sessionid][$sideid]);
|
||||
}
|
||||
|
@ -188,6 +184,44 @@ class ChatDaemon {
|
|||
global $CFG;
|
||||
|
||||
switch($type) {
|
||||
case CHAT_SIDEKICK_BEEP:
|
||||
// Incoming beep
|
||||
$msg = &New stdClass;
|
||||
$msg->chatid = $this->sets_info[$sessionid]['chatid'];
|
||||
$msg->userid = $this->sets_info[$sessionid]['userid'];
|
||||
$msg->groupid = $this->sets_info[$sessionid]['groupid'];
|
||||
$msg->system = 0;
|
||||
$msg->message = 'beep '.$customdata['beep'];
|
||||
$msg->timestamp = time();
|
||||
|
||||
// Commit to DB
|
||||
insert_record('chat_messages', $msg);
|
||||
|
||||
// OK, now push it out to all users
|
||||
$this->message_broadcast($msg, $this->sets_info[$sessionid]['user']);
|
||||
|
||||
// Update that user's lastmessageping
|
||||
$this->update_lastmessageping($sessionid, $msg->timestamp);
|
||||
|
||||
// We did our work, but before slamming the door on the poor browser
|
||||
// show the courtesy of responding to the HTTP request. Otherwise, some
|
||||
// browsers decide to get vengeance by flooding us with repeat requests.
|
||||
|
||||
$header = "HTTP/1.1 200 OK\n";
|
||||
$header .= "Connection: close\n";
|
||||
$header .= "Date: ".date('r')."\n";
|
||||
$header .= "Server: Moodle\n";
|
||||
$header .= "Content-Type: text/html\n";
|
||||
$header .= "Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT\n";
|
||||
$header .= "Cache-Control: no-cache, must-revalidate\n";
|
||||
$header .= "Expires: Wed, 4 Oct 1978 09:32:45 GMT\n";
|
||||
$header .= "\n";
|
||||
|
||||
// That's enough headers for one lousy dummy response
|
||||
chat_socket_write($handle, $header);
|
||||
// All done
|
||||
break;
|
||||
|
||||
case CHAT_SIDEKICK_USERS:
|
||||
/*
|
||||
//$x = pusers($this->sets_info[$sessionid]['chatid'], $this->sets_info[$sessionid]['groupid']);
|
||||
|
@ -250,7 +284,7 @@ class ChatDaemon {
|
|||
break;
|
||||
case CHAT_SIDEKICK_MESSAGE:
|
||||
// Incoming message
|
||||
$msg = &New ChatMessage;
|
||||
$msg = &New stdClass;
|
||||
$msg->chatid = $this->sets_info[$sessionid]['chatid'];
|
||||
$msg->userid = $this->sets_info[$sessionid]['userid'];
|
||||
$msg->groupid = $this->sets_info[$sessionid]['groupid'];
|
||||
|
@ -356,11 +390,11 @@ class ChatDaemon {
|
|||
|
||||
$this->dismiss_half($sessionid, false);
|
||||
chat_socket_write($this->conn_sets[$sessionid][CHAT_CONNECTION_CHANNEL], $CHAT_HTMLHEAD_JS);
|
||||
trace('Finalized client: sid: '.$sessionid.' uid: '.$chatuser->userid.' gid: '.intval($groupid));
|
||||
trace('Connection accepted: '.$this->conn_sets[$sessionid][CHAT_CONNECTION_CHANNEL].', SID: '.$sessionid.' UID: '.$chatuser->userid.' GID: '.intval($groupid));
|
||||
|
||||
// Finally, broadcast the "entered the chat" message
|
||||
|
||||
$msg = &New ChatMessage;
|
||||
$msg = &New stdClass;
|
||||
$msg->chatid = $chatuser->chatid;
|
||||
$msg->userid = $chatuser->userid;
|
||||
$msg->groupid = 0;
|
||||
|
@ -379,7 +413,7 @@ class ChatDaemon {
|
|||
return false;
|
||||
}
|
||||
foreach($this->conn_ufo as $id => $ufo) {
|
||||
if($ufo == $handle) {
|
||||
if($ufo->handle == $handle) {
|
||||
// OK, got the id of the UFO, but what is it?
|
||||
|
||||
if($type & CHAT_SIDEKICK) {
|
||||
|
@ -402,11 +436,12 @@ class ChatDaemon {
|
|||
|
||||
if($type & CHAT_CONNECTION) {
|
||||
// This forces a new connection right now...
|
||||
trace('Incoming connection from '.$ufo->ip.':'.$ufo->port);
|
||||
|
||||
// Do we have such a connection active?
|
||||
if(isset($this->conn_sets[$sessionid])) {
|
||||
// Yes, so regrettably we cannot promote you
|
||||
trace('UFO #'.$id.' with '.$ufo.' cannot be promoted: session '.$sessionid.' is already final');
|
||||
trace('Connection rejected: session '.$sessionid.' is already final');
|
||||
$this->dismiss_ufo($handle);
|
||||
return false;
|
||||
}
|
||||
|
@ -425,14 +460,6 @@ class ChatDaemon {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
// It's the first one for that sessionid, so it will start an incomplete connection
|
||||
$this->conn_half[$sessionid] = array($type => $handle);
|
||||
unset($this->conn_ufo[$id]);
|
||||
trace('UFO #'.$id.': identified session '.$sessionid.' wintype '.$type);
|
||||
return true;
|
||||
*/
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -444,8 +471,8 @@ class ChatDaemon {
|
|||
}
|
||||
if($disconnect) {
|
||||
foreach($this->conn_half[$sessionid] as $handle) {
|
||||
socket_shutdown($handle);
|
||||
socket_close($handle);
|
||||
@socket_shutdown($handle);
|
||||
@socket_close($handle);
|
||||
}
|
||||
}
|
||||
unset($this->conn_half[$sessionid]);
|
||||
|
@ -453,14 +480,13 @@ class ChatDaemon {
|
|||
}
|
||||
|
||||
function dismiss_set($sessionid) {
|
||||
if(!isset($this->conn_sets[$sessionid])) {
|
||||
return false;
|
||||
}
|
||||
if(!empty($this->conn_sets[$sessionid])) {
|
||||
foreach($this->conn_sets[$sessionid] as $handle) {
|
||||
// Since we want to dismiss this, don't generate any errors if it's dead already
|
||||
@socket_shutdown($handle);
|
||||
@socket_close($handle);
|
||||
}
|
||||
}
|
||||
unset($this->conn_sets[$sessionid]);
|
||||
unset($this->sets_info[$sessionid]);
|
||||
return true;
|
||||
|
@ -472,7 +498,7 @@ class ChatDaemon {
|
|||
return false;
|
||||
}
|
||||
foreach($this->conn_ufo as $id => $ufo) {
|
||||
if($ufo == $handle) {
|
||||
if($ufo->handle == $handle) {
|
||||
unset($this->conn_ufo[$id]);
|
||||
if($disconnect) {
|
||||
chat_socket_write($handle, "You don't seem to be a valid client.\n");
|
||||
|
@ -491,21 +517,18 @@ class ChatDaemon {
|
|||
return false;
|
||||
}
|
||||
|
||||
$newconn = &New ChatConnection;
|
||||
$newconn->handle = $handle;
|
||||
socket_getpeername($newconn->handle, &$newconn->ip, &$newconn->port);
|
||||
|
||||
$newconn = &New ChatConnection($handle);
|
||||
$id = $this->new_ufo_id();
|
||||
//trace('UFO #'.$id.': connection from '.$newconn->ip.' on port '.$newconn->port.', '.$newconn->handle);
|
||||
$this->conn_ufo[$id] = $newconn;
|
||||
|
||||
$this->conn_ufo[$id] = $newconn->handle;
|
||||
//trace('UFO #'.$id.': connection from '.$newconn->ip.' on port '.$newconn->port.', '.$newconn->handle);
|
||||
}
|
||||
|
||||
function conn_activity_ufo (&$handles) {
|
||||
$monitor = array();
|
||||
if(!empty($this->conn_ufo)) {
|
||||
foreach($this->conn_ufo as $ufoid => $ufo) {
|
||||
$monitor[$ufoid] = $ufo;
|
||||
$monitor[$ufoid] = $ufo->handle;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -545,7 +568,7 @@ class ChatDaemon {
|
|||
// and THEN broadcast a message to all others... otherwise, infinite recursion.
|
||||
|
||||
delete_records('chat_users', 'sid', $sessionid);
|
||||
$msg = &New ChatMessage;
|
||||
$msg = &New stdClass;
|
||||
$msg->chatid = $info['chatid'];
|
||||
$msg->userid = $info['userid'];
|
||||
$msg->groupid = 0;
|
||||
|
@ -585,12 +608,13 @@ define('CHAT_SIDEKICK', 0x20);
|
|||
// Sidekicks: Incrementing sequence, 0x21 to 0x2f
|
||||
define('CHAT_SIDEKICK_USERS', 0x21);
|
||||
define('CHAT_SIDEKICK_MESSAGE', 0x22);
|
||||
define('CHAT_SIDEKICK_BEEP', 0x23);
|
||||
|
||||
|
||||
$DAEMON = New ChatDaemon;
|
||||
$DAEMON->socket_active = false;
|
||||
$DAEMON->trace_level = E_ALL;
|
||||
$DAEMON->socketserver_refresh = 10;
|
||||
$DAEMON->socketserver_refresh = 20;
|
||||
$DAEMON->can_daemonize = function_exists('pcntl_fork');
|
||||
$DAEMON->beepsoundsrc = $CFG->wwwroot.'/mod/chat/beep.wav';
|
||||
$DAEMON->live_data_update_threshold = 30;
|
||||
|
@ -649,13 +673,10 @@ if(!socket_bind($DAEMON->listen_socket, $CFG->chat_serverip, $CFG->chat_serverpo
|
|||
$DAEMON->last_error = socket_last_error();
|
||||
echo "Error: socket_bind() failed: ". socket_strerror(socket_last_error($DAEMON->last_error)).' ['.$DAEMON->last_error."]\n";
|
||||
|
||||
// If $DAEMON->last_error == 98 (Success), maybe we need to try cleaning up a bit before dying
|
||||
// This is EXPERIMENTAL code!
|
||||
if($DAEMON->last_error == 98) {
|
||||
trace('experimental fix kicks in');
|
||||
socket_close($DAEMON->listen_socket);
|
||||
}
|
||||
if($DAEMON->last_error != 98) {
|
||||
die();
|
||||
}
|
||||
|
||||
}
|
||||
if(!socket_listen($DAEMON->listen_socket, $CFG->chat_servermax)) {
|
||||
// Failed to get socket to listen
|
||||
|
@ -743,7 +764,7 @@ while(true) {
|
|||
continue;
|
||||
}
|
||||
|
||||
if(!ereg('win=(chat|users|message).*&chat_sid=([a-zA-Z0-9]*)&groupid=([0-9]*) HTTP', $data, $info)) {
|
||||
if(!ereg('win=(chat|users|message|beep).*&chat_sid=([a-zA-Z0-9]*)&groupid=([0-9]*) HTTP', $data, $info)) {
|
||||
// Malformed data
|
||||
trace('UFO with '.$handle.': Request with malformed data; connection closed', E_USER_WARNING);
|
||||
$DAEMON->dismiss_ufo($handle);
|
||||
|
@ -763,6 +784,17 @@ while(true) {
|
|||
case 'users':
|
||||
$type = CHAT_SIDEKICK_USERS;
|
||||
break;
|
||||
case 'beep':
|
||||
$type = CHAT_SIDEKICK_BEEP;
|
||||
if(!ereg('beep=([^&]*)[& ]', $data, $info)) {
|
||||
trace('Beep sidekick did not contain a valid userid', E_USER_WARNING);
|
||||
$DAEMON->dismiss_ufo($handle);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
$customdata = array('beep' => intval($info[1]));
|
||||
}
|
||||
break;
|
||||
case 'message':
|
||||
$type = CHAT_SIDEKICK_MESSAGE;
|
||||
if(!ereg('chat_message=([^&]*)[& ]', $data, $info)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue