使用python和tornado实现多人网页聊天程序

2 篇文章 0 订阅
2 篇文章 0 订阅

使用python和tornado实现多人聊天界面

-------------------不要完全盗用哦~----------------------
功能包括:登录、注册、聊天、多人聊天室、增加聊天室。

建议先了解基础知识:

1.python

2.tonado

3.numpy

4.Visual Studio Code编程环境

实验设计
(包括项目结构、方案简要说明等)(1) 项目结构:对于本次项目,项目结构分为chatHander.py后端处理程序、templates文件(包含各种用到的html文件)、static文件(包含用到的图片,js文件和css文件)
方案说明
1.对于实现多人聊天室的功能:·登录页面。登录页面让用户输入用户账户和密码进行登录,后端能获得用户输入的信息,并且对用户的信息进行验证处理,所以后端需要有一个保存用户信息的变量,如果用户信息验证不过,则需要跳转到出错页面或者注册页面。
2.注册页面。用户首次登陆必须要注册账号,后端保存新的用户信息,注册成功后将跳转到 登陆页面登录。注册页面又有密码验证功能,如果用户两次输入的密码不同,将会跳转到出错页面,将出错信息输出再跳转回注册界面。
3.聊天室首页面。用户在登录成功后晶进入个人用户主页面,功能包含聊天室编号、创建新的聊天室、刷新页面、退出登录。

  • 聊天室编号:显示当前所有聊天室,用户点击后将直接进入聊天页面。
  • 创建新的聊天室:用户可以选择创建新的聊天室,点击后进入聊天室设置(设置聊天室名字)。
  • 刷新页面:当前有人创建了新的聊天室,但对于其他用户停留在主页面时,需要刷新才能显示出新的聊天室。
  • 退出登录:点击后,用户退出登录,将进入登录界面。可以选择更换账号登录。
  • 聊天页面。用户选择聊天室,进入聊天页面,功能上用户可以发送消息,可以选择回到主 页面再选择聊天室。
  • 创建新的聊天室。用户选择创建新的聊天室,进入设置页面,设置新的聊天室名字,创建后直接返回用户的主页面,并把所有聊天室显示出来。
  • 出错页面。前面提到的错误在出错页面可以将错误信息显示出来,通过自动跳转,回到指定的路由url。

源代码
chatHandler.py
1.后端代码:

# -*-coding:utf-8-*-
import json
import tornado.web
import tornado.websocket
import tornado.httpserver
import tornado.ioloop
import tornado.options
from uuid import uuid4
import time
import numpy as np

np.random.seed(1234)

ls = ['*', '**', '***', '#', '##', '###', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
      'g', 'h', 'i', 'j']
users_info = {'ABC': '12345678', 'hhm': '123456'}  # 保存所有用户的账户和密码信息
users_data = {'1': {}, '2': {}}  # 保存所有聊天室下、所有用户在线时所记录的各种聊天信息,用于保存历史记录
online = []  # 以用户名来保存当前登录的用户
users_nums = {}  # 记录每个聊天室在线的成员,用于显示在线人数。


class LoginHandler(tornado.web.RequestHandler):
    '''
    登录:
    用户选择直接登录或者注册新账户;
    用户信息验证过程;
    出错信息和跳转;
    '''

    def get(self, *args, **kwargs):
        self.render("login.html", type_="login")  # 登陆页面

    def post(self, *args, **kwargs):
        # 信息验证和出错管理
        username = str(self.get_argument("id"))
        passwd = str(self.get_argument("passwd"))
        if username in users_info:
            if username in online:
                online.remove(username)
                self.render('error.html',
                            info={'status': False,
                                  'errorcontnet': '友情提示!',
                                  'info': "该用户已经在线!将自动跳转界面",
                                  'second': 2,
                                  'url': '/basic/?u=%s' % (username),
                                  }
                            )
            else:
                if passwd == users_info[username]:
                    online.append(username)
                    self.render(
                        'basic.html',
                        id=username,
                        session=username,
                        rooms=users_data,
                    )  # 进入
                else:
                    self.render('error.html',
                                info={'status': False,
                                      'errorcontnet': '出错了》~《',
                                      'info': "用户名密码错误!将自动跳转注册界面",
                                      'second': 3,
                                      'url': '/login',
                                      }
                                )

        else:
            self.render(
                "error.html",
                info={'status': False,
                      'errorcontnet': '出错了》~《',
                      'info': "该用户没有注册,请先注册!将自动跳转注册界面",
                      'second': 2,
                      'url': '/register/',
                      },
            )


class RegisterHandler(tornado.web.RequestHandler):
    '''
    注册:
    新用户注册信息注册和验证;
    出错信息和跳转;
    '''

    def get(self, *args, **kwargs):
        self.render('register.html')  # 注册页面

    def post(self, *args, **kwargs):
        # 信息验证和出错管理
        username = self.get_argument('id')
        passwd = self.get_argument('passwd')
        passwd1 = self.get_argument('passwd1')

        if username not in users_info:
            if passwd == passwd1:
                users_info[username] = passwd
                self.render(
                    'success.html',
                    info={
                        'status': True,
                        'info': "注册成功!自动跳转登录界面",
                        'second': 2,
                        'url': '/login',
                    }
                )
            else:
                self.render(
                    'error.html',
                    info={
                        'status': False,
                        'errorcontnet': '出错了》~《',
                        'info': "密码不一致!自动跳转注册界面",
                        'second': 2,
                        'url': '/register/',
                    }
                )
        else:
            self.render(
                'error.html',
                info={
                    'status': False,
                    'errorcontnet': '出错了》~《',
                    'info': "用户已经注册!",
                    'second': 5,
                    'url': '/login',
                }
            )


class chatBasicHandler(tornado.web.RequestHandler):
    '''
        主页:
        选择进入聊天室;
        创建聊天室;
    '''

    def get(self, *args, **kwargs):
        u = self.get_argument("u")
        # 进入用户聊天室主页面
        self.render('basic.html',
                    id=u,
                    session=u,
                    rooms=users_data,
                    )

    def post(self, *args, **kwargs):
        # 用户聊天室创建
        room_name = str(self.get_argument("new_room"))
        u = self.get_argument("u")
        if room_name in users_data:
            room_name = room_name + '**'
            users_data[room_name] = {}
            self.redirect('/basic')
        else:
            users_data[room_name] = {}
            self.redirect('/basic')


class CreateHandler(tornado.web.RequestHandler):
    '''
    创建聊天室:
    设置聊天室名字
    '''

    def get(self, *args, **kwargs):
        u = self.get_argument('u')
        self.render(
            'create.html',
            id=u,
        )

    def post(self, *args, **kwargs):
        u = self.get_argument('u')
        room_name = str(self.get_argument("new_room"))
        if room_name in users_data:
            v = np.random.choice(ls, 1, False)
            room_name = room_name + str(v[0])
            users_data[room_name] = {}
            self.redirect('/basic/?u=%s' % (u))

        else:
            users_data[room_name] = {}
            self.redirect('/basic/?u=%s' % (u))


class homeHandler(tornado.web.RequestHandler):
    '''
        聊天室, 获取主页选择聊天室跳转的get信息渲染页面
    '''

    def get(self, *args, **kwargs):
        n = self.get_argument('n')  # 聊天室
        u = self.get_argument('u')  # 用户
        self.render('home.html', n=n, u=u, id=u)


class newChatStatus(tornado.websocket.WebSocketHandler):
    '''
        websocket, 记录客户端连接,删除客户端连接,接收最新消息
    '''
    users = {}  # 在线的用户(以类信息保存)
    time = 0  # 记录时间

    # 进入聊天室
    def open(self):
        # 显示时间
        self.time = time.time()
        self.write_message(json.dumps({'from': 'sys', 'message': '%s' % (time.strftime('%Y-%m-%d %H:%M:%S'))}))

        n = str(self.get_argument('n'))  # 聊天室
        u = str(self.get_argument('u'))  # 用户
        # 记录在线的用户(全局保存,且以用户名保存)
        if u in online:
            pass
        else:
            online.append(u)
        # 记录每个房间时在线人数
        if n in users_nums:
            users_nums[n].append(u)
        else:
            users_nums[n] = []
            users_nums[n].append(u)
        # 向新加入用户发送首次消息
        self.write_message(json.dumps({'from': 'sys', 'message': '欢迎%s来到 聊天室(%s)' % (u, n)}))
        # 显示历史记录
        if n in users_data:
            if u in users_data[n]:
                for m in users_data[n][u]:
                    self.write_message(json.dumps({'from': m[0], 'message': m[1]}))
        # 添加在线用户(类信息)
        if n in self.users:
            self.users[n].append(self)
        else:
            self.users[n] = [self]
        message = {
            'from': 'sys', 'message': '%s加入聊天室%s(当前%d人在线)' % (u, n, len(users_nums[n]))
        }
        # 向每个聊天室成员发送消息
        for user in self.users[n]:
            user.write_message(json.dumps(message))

    # 离开聊天室
    def on_close(self):

        n = str(self.get_argument('n'))  # 聊天室
        u = str(self.get_argument('u'))  # 用户
        online.remove(u)  # 删除离开聊天室的用户
        # 人数减1
        if n in users_nums:
            if u in users_nums[n]:
                users_nums[n].remove(u)
        # 删除用户(类信息
        self.users[n].remove(self)
        if self.users[n]:
            message = {
                'from': 'sys',
                'message': '%s离开了聊天室%s(当前%d人在线)' % (u, n, len(users_nums[n]))
            }
            # 向聊天室里的每个成员发送消息
            for user in self.users[n]:
                user.write_message(json.dumps(message))

    # 用户发送消息
    def on_message(self, message):
        t1 = time.time()
        # 定时显示消息
        if t1 - self.time > 120:
            self.time = t1
            self.write_message(json.dumps({'from': 'sys', 'message': '%s' % (time.strftime('%Y-%m-%d %H:%M:%S'))}))

        n = str(self.get_argument('n'))
        u = str(self.get_argument('u'))
        message = {'from': u, 'message': message}

        # 保存用户发送的消息,只要在线的都要保存
        if n in users_data:
            for user in users_nums[n]:
                if user in users_data[n]:
                    users_data[n][user].append((u, message['message']))
                else:
                    users_data[n][user] = []
                    users_data[n][user].append((u, message['message']))
        else:
            users_data[n] = {}
            for user in users_nums[n]:
                users_data[n][user] = []
                users_data[n][user].append((u, message['message']))

        # 向每个在线人员发送新消息
        for user in self.users[n]:
            user.write_message(json.dumps(message))


class Application(tornado.web.Application):
    def __init__(self):
        handlers = [
            (r'/login', LoginHandler),
            (r'/register/', RegisterHandler),
            (r'/home/', homeHandler),
            (r'/basic/', chatBasicHandler),
            (r'/newChatStatus/', newChatStatus),
            (r'/create/', CreateHandler),

        ]
        settings = {
            'template_path': 'template',
            'static_path': 'static'
        }

        tornado.web.Application.__init__(self, handlers, **settings)


if __name__ == '__main__':
    tornado.options.parse_command_line()
    server = tornado.httpserver.HTTPServer(Application())
    server.listen(8000)  # 监听端口
    tornado.ioloop.IOLoop.instance().start()

剩余代码请参见我的下一个博客

谢谢你的浏览~
-------------------不要完全盗用哦~----------------------

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的使用PythonTornado框架实现Stripe支付接口的例子: ```python import tornado.ioloop import tornado.web import stripe class PaymentHandler(tornado.web.RequestHandler): def post(self): stripe.api_key = "sk_test_your_secret_key" token = self.get_argument("stripeToken") amount = int(self.get_argument("amount")) description = self.get_argument("description") try: charge = stripe.Charge.create( amount=amount, currency="usd", description=description, source=token, ) self.write("Payment is successful!") except stripe.error.CardError as e: self.write("Card declined: %s" % e) if __name__ == "__main__": app = tornado.web.Application([ (r"/payment", PaymentHandler), ]) app.listen(8888) tornado.ioloop.IOLoop.current().start() ``` 在这个例子中,我们创建了一个名为PaymentHandler的请求处理器,当客户端使用POST方法请求/payment路径时,会触发这个处理器的post方法。在post方法中,我们首先设置了Stripe的API密钥,然后从请求中获取了支付所需的参数,包括支付金额、付款描述和Stripe令牌。最后,我们调用了Stripe的Charge.create方法,创建了一个新的支付,并在支付成功或者失败时返回相应的信息。 需要注意的是,这个例子中的Stripe API密钥是测试密钥,仅用于开发和测试,如果您需要在生产环境中使用Stripe支付接口,请使用生产密钥。 希望这个例子能够帮助您实现Stripe支付接口的调用。如果您还有其他问题,请随时提出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值