72f4ba51b784673a15a1e89d8d9f49d1

This code is the main function in an IRC bot, and runs through a number of conditions to check for new lines to interpret, running certain functions as a result. update_http() currently only runs when there is a new message incoming on the socket. How can we make it constantly loop, regardless of socket status, but still parse our other data?

<?php
function ircinit()
{
	global $con, $CONFIG, $channels, $last_chat;
	/* We need this to see if we need to JOIN (the channel) during
	the first iteration of the main loop */
	$firstTime = true;
	
	/* Connect to the irc server */
	$con['socket'] = fsockopen($CONFIG['server'], $CONFIG['port']);
	
	/* Check that we have connected */
	if (!$con['socket']) {
		print ("\nCould not connect to: ". $CONFIG['server'] ." on port ". $CONFIG['port']);
	} else {
		/* Send the username and nick */
		cmd_send("USER ". $CONFIG['nick'] ." roleplaygateway.com roleplaygateway.com :". $CONFIG['name']);
		cmd_send("NICK ". $CONFIG['nick'] ." roleplaygateway.com");
		
		/* Here is the loop. Read the incoming data (from the socket connection) */
		while (!feof($con['socket']))
		{
			/* Think of $con['buffer']['all'] as a line of chat messages.
			We are getting a 'line' and getting rid of whitespace around it. */
			$con['buffer']['all'] = trim(fgets($con['socket'], 4096));
			
			/* Pring the line/buffer to the console
			I used <- to identify incoming data, -> for outgoing. This is so that
			you can identify messages that appear in the console. */
			print date("[d/m @ H:i]")."<- ".$con['buffer']['all'] ."\n";
			
			/* If the server is PINGing, then PONG. This is to tell the server that
			we are still here, and have not lost the connection */
			if(substr($con['buffer']['all'], 0, 6) == 'PING :') {
				/* PONG : is followed by the line that the server
				sent us when PINGing */
				cmd_send('PONG :'.substr($con['buffer']['all'], 6));
				/* If this is the first time we have reached this point,
				then JOIN the channel */
				if ($firstTime == true){
					//cmd_send("JOIN ". $CONFIG['channel']);
					// for all the channels we want to join
					foreach ($channels as $chan)
					{
						cmd_send("JOIN ".$chan);			
					}
					/* The next time we get here, it will NOT be the firstTime */
					$firstTime = false;
				}
			} elseif (preg_match("/:NickServ!services@services.SC.net NOTICE HAL :This nickname is registered and protected./",$con['buffer']['all'])) {
				/* Need to register */
				register();
				/* Make sure that we have a NEW line of chats to analyse. If we don't,
				there is no need to parse the data again */
			} elseif ($old_buffer != $con['buffer']['all']) {
				/* Determine the patterns to be passed
				to parse_buffer(). buffer is in the form:
				:username!~identd@hostname JOIN :#php
				:username!~identd@hostname PRIVMSG #PHP :action text
				:username!~identd@hostname command channel :text */

			
				// log the buffer to "log.txt" (file must have
				// already been created).
				//log_to_file($con['buffer']['all']);

				// make sense of the buffer
				parse_buffer();
				
				// now process any commands issued to the bot
				process_commands();
				
			}
			
			update_http();
					
			$old_buffer = $con['buffer']['all'];
		}
	}
}
?>

Refactorings

No refactoring yet !

353d83d3677b142520987e1936fd093c

Daniel O'Connor

March 20, 2008, March 20, 2008 12:05, permalink

No rating. Login to rate!

The regular way to do this is misleadingly simple - a for (;;) { } loop or while (true) { }. To give your script a little bit of breathing space, usleep() can help

<?php
function main() {
   
   while (true) {
       //Check for new data on the socket, and process it

       //Otherwise, go away for 0.2 seconds
       usleep(200000);
   }
}
?>
8bba46dba9043c254e6eef1aa664e6f0

EllisGL

December 10, 2008, December 10, 2008 17:40, permalink

No rating. Login to rate!

Actually you can use a do{}while(); to be a little bit more efficient.

function main()
 {
  do
   {
    //Check for new data on the socket, and process it

    //Otherwise, go away for 0.2 seconds
    usleep(200000);
   }while(1);
 }
54bc89bb060fcd6954c39cd791ccb2cf

Rich

March 23, 2011, March 23, 2011 12:31, permalink

No rating. Login to rate!

I'm intrigued as to why do while() is more efficient than while == true

Having a small sleep between iterations makes sense, though if you're accepting multiple connections to the socket server then the delay could cause a backlog and eventually lead to connections being refused, depending on what value is set for socket_listen()

Your refactoring





Format Copy from initial code

or Cancel