Source code for socktools.examples.simple_chat

"""
Python Sock tools: simple_chat.py - multiuser "chat" implementation
Copyright (C) 2016 GarethNelson

This file is part of python-sock-tools

python-sock-tools is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

python-sock-tools is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with python-sock-tools.  If not, see <http://www.gnu.org/licenses/>.

This module implements a toy multiuser chat server, clients can connect using standard tools like netcat and telnet and chat to other clients.

If you want to test it, simply run it as a normal python script and then connect to localhost on port 31337.

Note: this is provided as an example only, it is highly recommended that you do NOT try to run a production server on this code as-is.
"""

import eventlet
eventlet.monkey_patch() # this should be done in all modules that use eventlet as the first import, just in case

from socktools import tcp_sock
from socktools import tcp_linemode_mixin

MSGTYPE_LINE = 0

[docs]class ChatProtocol(tcp_linemode_mixin.TCPLinemodeMixin,tcp_sock.TCPSock): """Multiuser chat implementation Protocols in socktools are either classes that inherit from a socket or mixins that can be added to another application-specific class later along with the socket. For the multiuser chat protocol we only want TCP, messages are simply newline terminated. Homework exercise: implement message types and use them to specify IRC-style channels, or outright implement IRC. Hint: you need handlers and a modified parser. """
[docs] def get_default_handlers(self): """ We setup handlers here In this example, there's only a single message type (0) - also known as the default message type Returns: dict: the message handlers dict, updated to configure message type 0 so it calls handle_msg """ handlers = super(ChatProtocol,self).get_default_handlers() # it's good practice to add the default handlers from upstream, even though it's pointless in this particular example handlers[MSGTYPE_LINE] = [self.handle_msg] return handlers
[docs] def handle_msg(self,from_addr,msg_type,msg_data): """ Handler for message type 0 By default, this is the only message handler used, others can of course be setup and should be done in get_default_handlers(). This method is also gloriously simple - it just broadcasts msg_data to all other connected clients. """ self.send_msg(MSGTYPE_LINE,msg_data)
[docs] def handle_all(self,from_addr,msg_type,msg_data): """All messages get transformed to show other users where they came from. See base_sock.py for information on this method. Note that it is generally not good style to use this method for doing actual application logic, it should only transform. Homework exercise: make users pseudo-anonymous by hashing their IP address and add in IRC-like ops with /kick and /ban functionality """ new_data = '<%s:%s> %s' % (from_addr[0],from_addr[1],msg_data) return (from_addr,msg_type,new_data)
if __name__=='__main__': import sys chat = ChatProtocol(bind=('127.0.0.1',31337)) print 'Starting server...' chat.start_server() print 'Hit ctrl-c to quit' while True: eventlet.greenthread.sleep(30)