RPyChat is a proof-of-concept for a chat client and server. RPyChat is meant to show how everything can be thought of as RPC: when the client logs in, it receives a UserToken object, which the client can use to send text to the server (and the other clients through it). This is a straight forward example of RPC. The key point of RPyChat, however, is that the server also uses RPC to send text to the client — when a client logs in, it also passes a callback function. The server will use this callback function to asynchronously notify the client of events.
Here's a simplified version of the server (the actual server code has some more boilerplate, but other than that, it is very similar):
all_client_callbacks = set() class UserToken(object): def __init__(self, name): self.name = name def exposed_say(text): for callback in all_client_callbacks: callback("[%s] %s" % (self.name, text)) class ChatService(rpyc.Service): def exposed_login(self, username, callback) all_client_callbacks.add(rpyc.async(callback)) return UserToken(username)
And the client, minus the GUI boilerplate:
class ChatClient(object): def __init__(self, host, port, username): # GUI code: create a window with a scrolled textbox called 'history', # a textline called 'text', and a button called 'send' # login code: self.conn = rpyc.connect(host, port) self.token = self.conn.root.login(username, self.show_text) # register the connection with the reactor, to be invoked when data is received gui_reactor.register_io_read(self.conn, self.background_handler) def on_send(self): self.token.send(self.text.getText()) def background_handler(self): self.conn.poll_all() # handle incoming background requests def show_text(self, text): self.history.append(text) # append the new text line to the history
Screenshot
| Three clients | Server running in a console |
![]() |
![]() |









