Understanding a Simple Asynchronous Telnet Server

Posted 26 February 2012 - 11:09 AM

Hi there everyone,
I've been messing around with programming with the miniboa module recently, and I'm confused as to how to wait for one particular user's input. I'm trying to create a MUD-like telnet server that pits a board game engine that I wrote against a client. The problem is most likely coming from a lack of understanding of how asynchronous networking works, but here are my goals with the program.

1) Allow clients to connect to my computer.
2) Allow clients to chat in the lobby
OR
3) Once a client enters a command, the server will play a game with the client.

The way that my board game engine works offline is relatively simple;

1) Prints the board to the user.
2) Waits on user input.
3) If the move is legal, it prints a new board with the user's move.
4) Prints a new board with the computer's move.
5) Repeat steps 2-5.

My confusion comes from a conflict between the way I want the engine to work online, and if it can be applied to an asynchronous server. Is this even reasonable? I tried to make a loop that waits until a valid move has been made by the client, but it just sticks the client and server in an infinite loop.

def interface(client):
print("Game interface started for %s\n" % (client.addrport()))
if client.active and client.cmd_ready:
client.send("Hello, and welcome to my first ever igo engine!\n")
client.send("I hope to make it around 20k one day, but right now\n")
client.send("it plays on a 50k level. It's good for a time-killer,\n")
client.send("and even better to take out your frustrations! Now\n")
client.send("that the introductions are out of the way, let's\n")
client.send("play!\n\n")
client.send("What sized board do you want to play on?\n")
valid_size = False
while valid_size == False:
try:
size = int(client.get_command())
if size <= 19 and size >= 2:
valid_size = True
else:
client.send("Oh no! That's not a valid board size!")
except ValueError:
client.send("Oh no! That's not a valid board size!")
self.single_player_match(client, size)

I've also tried to just explicitly call the client.get_command(), but it just returns the None type.

Replies To: Understanding a Simple Asynchronous Telnet Server

Re: Understanding a Simple Asynchronous Telnet Server

Posted 26 February 2012 - 01:48 PM

I've made some progress with my engine! I figured out that the way I called my data was entirely wrong. This is my new approach:

def menu(client):
print("Game interface started for %s\n" % (client.addrport()))
CLIENT_IN_MENU.append(client)
client.send("Hello, and welcome to my first ever igo engine!\n")
client.send("I hope to make it around 20k one day, but right now\n")
client.send("it plays on a 50k level. It's good for a time-killer,\n")
client.send("and even better to take out your frustrations! Now\n")
client.send("that the introductions are out of the way, let's\n")
client.send("play!\n\n")
client.send("What sized board do you want to play on?\n")
def menu_choice(client):
global SERVER_RUN
size = client.get_command()
try:
size = int(size)
except TypeError or ValueError:
client.send("Oh no! That's not a valid board size!\n")
if size <= 19 and size >= 2:
CLIENT_IN_MENU.remove(client)
debug_menu(client, size)
else:
client.send("Oh no! That's not a valid board size!\n")

To clarify, I'll try to make a flow chart of both processes' intents. The old method's plan was something like this:

1) Get input from clients in the main loop.
2) Check if the text entered was in the command list. If so, it would execute the command. If not, it would echo the chat to all other clients.
3) The command would ask the client for input through a loop that verified if the input was valid (this would work for synchronous networks, not asynchronous in theory. In my example it tried to pull non-existent data from itself, while avoiding collecting actual input from the main loop.)
4) The server would interpret the command and start a game. (I didn't get this far, but this is where I wanted to go.)

This is the new method:

1) Get input from clients in the main loop.
2) Check if the text entered was in the command list. If so, it would execute the command. If not, it would echo the chat to all other clients.
3) The command would turn on a switch for that specific client.
4) Ask for input, then put the user back in the main loop.
5) It would then make sure that all input would be directed toward the command.
6) If the input is valid, it would direct the variable that the input is stored in to the game.
7) The game itself would handle it's input in a similar manner, except it appends data to a list in the following format: [client, game_number].

I haven't gotten to the actual game engine bit yet, but I think now that I've identified this problem, it'll be smooth sailing here on out.