文档章节

python的多人多功能聊天室

疯狂的小企鹅
 疯狂的小企鹅
发布于 2014/06/21 11:46
字数 899
阅读 233
收藏 1
点赞 0
评论 0

从Beginning Python: From Novice to Professional, Second Edition 中的一个chatroom项目中拿出来的。那里的聊天室,只有一个单间聊天室功能,使用asyncore和asynchat实现,只能群聊。后来我给它加上了多人聊天室功能。还加上了私聊等功能。改用twisted实现并把它变成了守护模式(使用twistd)

命令列表:

/login username [roomname]

/who 查看当前登录的用户

/look 查看在当前聊天房间的用户

/to username content 私信用户

/exit 退出当前聊天房间

/logout 退出聊天服务器


代码如下:

from twisted.internet import reactor
from twisted.internet.protocol import Protocol,Factory
from twisted.internet import defer
from twisted.protocols.basic import LineReceiver
from twisted.application import internet,service
from twisted.python import log


class commaneHandler:
    def handle(self,session,line):
        if not line.strip():return
        parts=line.split(' ',1)
        cmd=parts[0].strip()
        try:
            if cmd[0]!='/':
                cmd="/say"
                line=line.strip()
            else:
                line=parts[1].strip()
        except IndexError:
            line=""
        finally:
            cmd=cmd[1:].strip()

        meth=getattr(self,"do_"+cmd,None)
        try:
            meth(session,line)
        except TypeError:
            self.unknow(session,cmd)

    def unknow(self,session,cmd):
        session.write("%s:unknow command!\n"%cmd)

                
class Room(commaneHandler):
    def __init__(self,server,name=""):
        self.server=server
        self.roomName=name
        self.sessions=[]

    def add(self,session):
        self.sessions.append(session)

    def remove(self,session):
        self.sessions.remove(session)

    def broadcast(self,line):
        for session in self.sessions:
            session.write(line+'\n')
    
    def do_list(self,session,line):
        session.write("list for ChatRoom\n")
        for room in self.server.rooms:
            session.write(room+'\n')
    
    def do_logout(self,session,line):
        session.entry(LogoutRoom(self.server))
        session.d.errback("")

class LoginRoom(Room):
    def add(self,session):
        Room.add(self,session)
        log.msg("Connection from %s "%session.session.getPeer())
        session.write("Welcome to ChatTest for twisted v1.1!\n")
    def do_login(self,session,line):
        parts=line.strip().split(" ")
        name=parts[0]
        if not name:
            session.write("Please entry a name\n")
        elif name in self.server.users:
            session.write("The name %s is token\n"%name)
        else:
            session.name=name
            try:
                roomName=parts[1]
            except IndexError:
                roomName="main"
            
            if not roomName in self.server.rooms:
                self.server.createRoom(roomName)
            session.entry(self.server.rooms[roomName])
    
    def unknow(self,session,line):
        session.write("Commands:login logout list\n")

class LogoutRoom(Room):
    def add(self,session):
        try:
            del self.server.users[session.name]
        except KeyError:
            pass

class ChatRoom(Room):
    def add(self,session):
        session.write("Welcome to ChatRoom:%s !\n"%self.roomName)
        mess=session.name+" has join the room"
        self.broadcast(mess)
        log.msg(mess)
        Room.add(self,session)
        self.server.users[session.name]=session
    
    def remove(self,session):
        Room.remove(self,session)
        self.broadcast(session.name+" has left the room")
        
    def do_say(self,session,line):
        self.broadcast("%s: %s"%(session.name,line))

    def do_look(self,session,line):
        session.write("list for room:\n")
        for i,other in enumerate(self.sessions):
            session.write("%d: %s\n"%(i,other.name))

    def do_exit(self,session,line):
        try:
            del self.server.users[session.name]
        except KeyError:
            pass
        session.entry(LoginRoom(self.server))

    def do_to(self,session,line):
        try:
            parts=line.split(' ',1)
            name=parts[0]
            line=parts[1]
            toUser=self.server.users[name]
            toUser.write("%s: %s\n"%(session.name,line))
        except IndexError:
            session.write("Usage:/to toUser line\n")
            return False
        except KeyError:
            session.write("%s does not exist!\n"%name)
            return False
        
    def do_who(self,session,line):
        session.write("list for server:\n")
        for i,name in enumerate(self.server.users.keys()):
            session.write("%d: %s\n"%(i,name))

class chatSession:
    def __init__(self,server,session,d):
        self.d=d
        self.server=server
        self.session=session
        self.name=None
        self.entry(LoginRoom(self.server,""))

    def write(self,line):
        self.session.write(line)

    def entry(self,room):
        try:
            cur=self.room
        except AttributeError:
            pass
        else:
            cur.remove(self)
        self.room=room
        room.add(self)

    def execComm(self,line):
        self.room.handle(self,line.strip())

class ChatProtocol(LineReceiver):
    
    def connectionMade(self):
        d=defer.Deferred()
        d.addBoth(self.endSession)
        self.s=chatSession(self.factory,self.transport,d)
    
    def endSession(self,_):
        self.transport.loseConnection()

    def connectionLost(self,reason):
        pass
    
    def connectionFailure(self,connector,reason):
        print reason


    def lineReceived(self,line):
        self.s.execComm(line)

class ChatFactory(Factory):
    protocol=ChatProtocol
    def __init__(self):
        self.users={}
        self.rooms={}
        self.createRoom("main")

    def createRoom(self,name):
        self.rooms[name]=ChatRoom(self,name)
        
port=1234
iface="localhost"
application=service.Application("chatRoom")
top_service=service.MultiService()
factory=ChatFactory()
tcp_service=internet.TCPServer(port,factory,
        interface=iface)
tcp_service.setServiceParent(top_service)
top_service.setServiceParent(application)

输出:

ljd&11:44:51:py$ twistd -n -y tw_chatRoom.py 

2014-06-21 11:45:01+0800 [-] Log opened.

2014-06-21 11:45:01+0800 [-] twistd 11.1.0 (/usr/bin/python 2.7.3) starting up.

2014-06-21 11:45:01+0800 [-] reactor class: twisted.internet.pollreactor.PollReactor.

2014-06-21 11:45:01+0800 [-] ChatFactory starting on 1234

2014-06-21 11:45:01+0800 [-] Starting factory <__builtin__.ChatFactory instance at 0xfe6368>

2014-06-21 11:45:09+0800 [__builtin__.ChatFactory] Connection from IPv4Address(TCP, '127.0.0.1', 58755) 

2014-06-21 11:45:23+0800 [ChatProtocol,0,127.0.0.1] abc has join the room


© 著作权归作者所有

共有 人打赏支持
疯狂的小企鹅

疯狂的小企鹅

粉丝 11
博文 42
码字总数 20243
作品 6
杭州
程序员
发送邮件给多人的python脚本

发送邮件给多人的python脚本: vi mail.py #!/usr/bin/python #coding=utf-8 import smtplib from email.mime.text import MIMEText import string host="smtp.126.com" sender='yangming@12......

yangzhimingg ⋅ 06/06 ⋅ 0

你真的了解Python吗?这篇文章让你了解90%

  【IT168 评论】人们为什么使用Python?   之所以选择Python的主要因素有以下几个方面:   软件质量:在很大程度上,Python更注重可读性、一致性和软件质量,从而与脚本语言世界中的其...

博客园 ⋅ 05/21 ⋅ 0

NovalIDE 1.1.1,跨平台的开源国产多功能 Python IDE

NovalIDE 1.1.1 正式发布了。 官方网址为:http://www.novalide.com 此次版本发布更新内容有: 主菜单添加了访问官方网站的入口 允许用户删除软件自带或内建的解释器,只保留一个用户自己的解...

东方玄 ⋅ 06/11 ⋅ 0

Python:经过了十几年,你们还没有消除的对我的误解吗?

摘要: 大学毕业到现在用的最多的编程语言还是C,C++,后来学习了一下Python,觉得Python是门学了不后悔的语言。尤其适合非程序员学习,作为青少年学习计算机的首门语言也不错,大学生学习计...

雁横 ⋅ 05/03 ⋅ 0

较为原生的WebSocket服务端

概念 个人理解它是客户端和服务端之间的通信通道 确定唯一一个socket(套接字)的属性需要4个 通过这4个属性不难在脑袋里抽象出通道的概念,两端分别是通道的入口和出口 函数解释(python im...

不洗碗工作室 ⋅ 04/18 ⋅ 0

CodeMirror 5.37.0 发布,多功能在线代码编辑器

CodeMirror 5.37.0 已发布,CodeMirror 是一款允许在浏览器中的多功能文本编辑器,专用于编辑代码,并附带超过 100 种语言模式和各种插件,可实现高级的代码编辑功能,包括代码高亮显示,功能...

王练 ⋅ 04/22 ⋅ 0

linux-Centos7安装python3并与python2共存

1.查看是否已经安装Python CentOS 7.2 默认安装了python2.7.5 因为一些命令要用它比如yum 它使用的是python2.7.5。 使用 python -V 命令查看一下是否安装Python 然后使用命令 which python 查...

lemonwater ⋅ 04/17 ⋅ 0

Centos下安装Python3.6

一、安装python3.6.1 1、安装依赖环境 #yum install readline-devel ##必须安装否则会出现python3编译器中不能使用退格键和方向键 2、下载安装包并解压 [root@bogon ~]# wget https://www.p...

argen2020 ⋅ 05/21 ⋅ 0

Centos7安装Python3

1.查看是否已经安装Python CentOS 7.2 默认安装了python2.7.5 因为一些命令要用它比如yum 它使用的是python2.7.5。 使用 python -V 命令查看一下是否安装Python 然后使用命令 which python 查...

xinrenbaodao ⋅ 04/19 ⋅ 0

ubuntu下Python的安装和使用

4.1 Python的安装 ubuntu下可以很方便的使用apt-get来安装软件,这里我们安装 Python 2.7/3.2(因为Python2和Python3区别很大)。安装步骤如下(下面的命令安装了两种)。 4.1.1 安装Python发...

JungleKing ⋅ 05/16 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

mysql in action / alter table

change character set ALTER SCHEMA `employees` DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci ;ALTER TABLE `employees`.`t2` CHARACTER SET = utf8mb4 , COLLAT......

qwfys ⋅ 今天 ⋅ 0

Java 开发者不容错过的 12 种高效工具

Java 开发者常常都会想办法如何更快地编写 Java 代码,让编程变得更加轻松。目前,市面上涌现出越来越多的高效编程工具。所以,以下总结了一系列工具列表,其中包含了大多数开发人员已经使用...

jason_kiss ⋅ 昨天 ⋅ 0

Linux下php访问远程ms sqlserver

1、安装freetds(略,安装在/opt/local/freetds 下) 2、cd /path/to/php-5.6.36/ 进入PHP源码目录 3、cd ext/mssql进入MSSQL模块源码目录 4、/opt/php/bin/phpize生成编译配置文件 5、 . ./...

wangxuwei ⋅ 昨天 ⋅ 0

如何成为技术专家

文章来源于 -- 时间的朋友 拥有良好的心态。首先要有空杯心态,用欣赏的眼光发现并学习别人的长处,包括但不限于工具的使用,工作方法,解决问题以及规划未来的能力等。向别人学习的同时要注...

长安一梦 ⋅ 昨天 ⋅ 0

Linux vmstat命令实战详解

vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况。这个命令是我查看Linux/Unix最喜爱的命令...

刘祖鹏 ⋅ 昨天 ⋅ 0

MySQL

查看表相关命令 - 查看表结构    desc 表名- 查看生成表的SQL    show create table 表名- 查看索引    show index from  表名 使用索引和不使用索引 由于索引是专门用于加...

stars永恒 ⋅ 昨天 ⋅ 0

easyui学习笔记

EasyUI常用控件禁用方法 combobox $("#id").combobox({ disabled: true }); ----- $("#id").combobox({ disabled: false}); validatebox $("#id").attr("readonly", true); ----- $("#id").r......

miaojiangmin ⋅ 昨天 ⋅ 0

金山WPS发布了Linux WPS Office

导读 近日,金山WPS发布了Linux WPS Office中文社区版新版本,支持大部分主流Linux系统,功能更加完善,兼容性、稳定性大幅度提升。本次更新WPS将首次在Linux提供专业办公文件云存储服务,实...

问题终结者 ⋅ 昨天 ⋅ 0

springboot2输出metrics到influxdb

序 本文主要研究一下如何将springboot2的metrics输出到influxdb maven <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-bo......

go4it ⋅ 昨天 ⋅ 0

微信小程序 - 选择图片显示操作菜单

之前我分享过选择图片这个文章,但是我在实际开发测试使用中发现一个问题在使用 wx.chooseImage 选择照片显示出第一格是拍照,后面是相册里的图片。这种实现之前说过了,效果如下。 但是你从...

hello_hp ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部