@TCL_STARTUP@

# server.tcl
#
# This is the "server_agent".  It waits for a meeting request from any client
# using the get_meeting command.  Then it asks the user whether to accept
# or reject the meeting.  The client and server exchange two strings if the
# user accepts the meeting.

  # register the agent on the current machine

if {[catch agent_begin]} {
  return -code error "ERROR: unable to register the agent on $agent(actual-server)"
}

if {[catch {

    # this is the "server_agent"

  catch {agent_force "$agent(local-ip) server_agent"}
  agent_name server_agent

    # process meeting requests forever

  while {1} {

      # wait for the next meeting request

    set source_id [get_meeting handle -blocking]

      # ask the user to accept or reject the meeting

    puts "--------------------------------------------------------------------------------"
    puts "$source_id requests access to the server"
    puts "Accept (Y/N)?"
    gets stdin answer

      # on acceptance establish the connection and exchange information
      # on rejection send a rejection notice

    set answer [string tolower $answer]

    if {($answer == "Y") || ($answer == "y")} {

	# accept the meeting

      accept_meeting $handle

	# wait for the meeting to complete 
	#
	# NOTE: In a real server, you would move the agent_select out to the 
	# main loop, e.g., the command
	#
        #    agent_select {meeting 5} -blocking
	#
	# waits for any new meeting request OR any change in the status of
	# an existing meeting with handle 5.  Thus the server could
	# simultaneously respond to both requests for NEW meetings and incoming
	# messages on EXISTING meetings.  The documentation contains more
	# details about agent_select.
	#
	# NOTE: If this were not a server that had to handle multiple meetings
	# at once, you could replace the accept_meeting and the entire
	# agent_select loop below with a single call to agent_meet, e.g.
	#
	#     agent_meet $source_id
	#
	# The reason *not* to do this in a real server is that the server would
	# be unresponive to other requests while it waited for the meeting to
	# complete (just like this fake server is now).

      while {1} {

	  # wait for the meeting to change state

	set statusList [agent_select $handle -blocking]

	  # Since we know that our statusList contains only one element,
	  # we can just lindex to get the status of the meeting.  If we
	  # were selecting on multiple things at once, we would need to use
	  # the foreach command to iterate through statusList instead.

	set status [lindex [lindex $statusList 0] 1]

	  # keep waiting if the meeting is still accepting or connection;
	  # otherwise break out of the loop

	if {($status != "accepting") && ($status != "connecting")} {
	  break
	}
      }

      if {$status != "complete"} {
	puts "ERROR: meeting failed with status $status"
	meeting_close $handle
	continue
      }

      meeting_receive $handle code string -blocking
      puts "The client $source_id says ...\n$string"
      meeting_send $handle "No problem!"
      meeting_close $handle

    } else {

      reject_meeting $handle
      meeting_close $handle
    }

    puts "--------------------------------------------------------------------------------"
  }
 
} error_message]} then {

    # make sure that we clean up on error

  agent_end

  return -code error -errorcode $errorCode -errorinfo $errorInfo $error_message
}

  # clean up

agent_end
