基于WebSocket的简易聊天室

用的是Flash + WebSocket 哦~

 Flask 之 WebSocket

一、项目结构:

二、导入模块

pip3 install gevent-websocket

三、先来看一个一对一聊天的代码

from flask import Flask, request, render_template
from geventwebsocket.websocket import WebSocket
from geventwebsocket.handler import WebSocketHandler
from gevent.pywsgi import WSGIServer

import json

# 创建 flask 对象
app = Flask(__name__)

# 跳转到所需 websocket 页面的视图函数
@app.route('/one-to-one')
def one_to_one_page():
    return render_template('one_to_one.html')


# 用来存放一对一聊天用户的连接  格式: {用户名 : 连接对象, ...}
one_to_one_user_dict = {}

# 一对一聊天
@app.route('/one-to-one/<username>')
def one_to_one(username):
    # 获取连接通道
    user_socket = request.environ.get('wsgi.websocket')
    if not user_socket:
        return '请使用websocket连接 '
    print(user_socket)
    one_to_one_user_dict[username] = user_socket
    while True:
        try:
            user_msg_json = user_socket.receive()
            user_msg = json.loads(user_msg_json)
            print(user_msg)
            # 如果发给的用户已连接,则发消息给对象
            if user_msg['to_user'] in one_to_one_user_dict:
                user_msg['code'] = True
                one_to_one_user_dict[user_msg['to_user']].send(json.dumps(user_msg))
            # 否则返回错误信息
            else:
                msg = {
                    'code': False,
                    'msg': '用户未登录',
                }
                user_socket.send(json.dumps(msg))

        except Exception as e:
            # 如果当前用户异常 将其从连接字典中删除
            if username in one_to_one_user_dict:
                one_to_one_user_dict.pop(username)
            print(e)
            break


if __name__ == '__main__':
    # 创建 wsgi server
    http_serv = WSGIServer(('0.0.0.0', 9527), app, handler_class=WebSocketHandler)
    #  持续运行 server
    http_serv.serve_forever()

在 one_to_one.html 页面里

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <style>
        #content {
            width: 100%;
            height: 200px;
            background-color: #e4e4e4;
        }
        #input {
            width: 100%;
            height: 50px;
        }
        .login {
            margin: 15px 0;
        }
        .self_info {
            color: #1004ff;
        }
        .self {
            margin-left: 100px;
        }
        .friend_info {
            color: red;

        }
        .friend {
            margin-right: 100px;
        }
        .friend_msg, .self_msg {
            width: 100%;
        }
    </style>
</head>
<body>
<div class="container">
    <div class="login">
        <div class="form-inline">
            <label for="in_login">用户名</label>
            <input id="in_login" type="text" class="form-control" placeholder="用户名">

            <label for="friend_name">好友名称</label>
            <input id="friend_name" type="text" class="form-control" placeholder="好友名称">

            <button id="b_login" type="submit" class="btn btn-default">Sign in</button>
        </div>
    </div>

    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-primary">
                <div class="panel-heading">
                    聊天室
                </div>
                <div id="content" class="panel-body">
                    <div class="friend_msg clearfix hide" >
                        <div class="pull-left friend">
                            <span class="friend_user">对方:</span>
                            <span class="friend_info"> 你好! </span>
                        </div>
                    </div>
                    <div class="self_msg clearfix hide">
                        <div class=" pull-right self">
                            <span class="self_info"> 你好 </span>
                            <span class="self_user">  : 我</span>
                        </div>
                    </div>
                </div>
            </div>

            <div id="input">
                <textarea id="input-info" class="form-control" rows="3"></textarea>
                <input id="submit" class="btn btn-default" type="submit" value="Submit">
            </div>
        </div>
    </div>
</div>

</body>
<script src="https://cdn.bootcss.com/jquery/3.3.0/jquery.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<script type="application/javascript">
    var ws_url = 'ws://127.0.0.1:9527/one-to-one/';
    var ws = null;
    {#var ws = new WebSocket('ws://127.0.0.1:9527/ws');#}
    {#ws.onopen = function () {#}
    {#ws.send('qweqwe')};#}

    //用户登录名
    var login_user
    var friend_name

    //登录:
    $('#b_login').click(function () {
        var user = $('#in_login').val();
        var friend = $('#friend_name').val();
        console.log('user', user);
        if (! (user && friend) ) {
            alert('用户或好友不能为空!!!')
        } else {
            login_user = user
            friend_name = friend
            console.log(ws_url + login_user);
            ws = new WebSocket(ws_url + login_user);

            //接收信息
            ws.onmessage = function (serv_msg) {
                serv_msg = JSON.parse(serv_msg.data)
                console.log('******secv********',serv_msg)
                if (serv_msg['code']){
                    var friend_info = serv_msg['send_msg'];
                    var friend_user = serv_msg['send_user'];
                    create_friend_msg(friend_info, friend_user)
                }else {
                    alert(serv_msg['msg'])
                }

            };
        }
    });

    //发送信息
    $('#submit').click(function () {
        var input_info = $('#input-info').val();
        var send_msg_json = {
            send_user: login_user,
            to_user: friend_name,
            send_msg: input_info
        };
        ws.send(JSON.stringify(send_msg_json));
        console.log(JSON.stringify(send_msg_json));
        create_self_msg(input_info);
        $('#input-info').val('');
    });

    //创建发出信息的标签
    function create_self_msg(input_info) {
        var $self_msg = $('.self_msg').first().clone();
        $self_msg.find('.self_info').text(input_info);
        $self_msg.find('.self_user').text('  : ' + login_user);
        $('#content').append($self_msg);
    };

    //创建收到信息的标签
    function create_friend_msg(friend_info, friend_user) {
        var $self_msg = $('.friend_msg').first().clone();
        $self_msg.find('.friend_info').text(friend_info);
        $self_msg.find('.friend_user').text(friend_user  + '  : ');
        $('#content').append($self_msg);
    };

</script>
</html>
one_to_one.html

重点看其中的 script

<script type="application/javascript">
    var ws_url = 'ws://127.0.0.1:9527/one-to-one/';
    var ws = null;
    {#var ws = new WebSocket('ws://127.0.0.1:9527/ws');#}
    {#ws.onopen = function () {#}
          {#ws.send('qweqwe')};#}

    //用户登录名
    var login_user
    var friend_name

    //登录:
    $('#b_login').click(function () {
        var user = $('#in_login').val();
        var friend = $('#friend_name').val();
        console.log('user', user);
        if (! (user && friend) ) {
            alert('用户或好友不能为空!!!')
        } else {
            login_user = user
            friend_name = friend
            console.log(ws_url + login_user);
            ws = new WebSocket(ws_url + login_user);

            //接收信息
            ws.onmessage = function (serv_msg) {
                serv_msg = JSON.parse(serv_msg.data)
                console.log('******secv********',serv_msg)
                if (serv_msg['code']){
                    var friend_info = serv_msg['send_msg'];
                    var friend_user = serv_msg['send_user'];
                    create_friend_msg(friend_info, friend_user)
                }else {
                    alert(serv_msg['msg'])
                }
            };
        }
    });

    //发送信息
    $('#submit').click(function () {
        var input_info = $('#input-info').val();
        var send_msg_json = {
            send_user: login_user,
            to_user: friend_name,
            send_msg: input_info
        };
        ws.send(JSON.stringify(send_msg_json));
        console.log(JSON.stringify(send_msg_json));
        create_self_msg(input_info);
        $('#input-info').val('');
    });

    //创建发出信息的标签
    function create_self_msg(input_info) {
        var $self_msg = $('.self_msg').first().clone();
        $self_msg.find('.self_info').text(input_info);
        $self_msg.find('.self_user').text('  : ' + login_user);
        $('#content').append($self_msg);
    };

    //创建收到信息的标签
    function create_friend_msg(friend_info, friend_user) {
        var $self_msg = $('.friend_msg').first().clone();
        $self_msg.find('.friend_info').text(friend_info);
        $self_msg.find('.friend_user').text(friend_user  + '  : ');
        $('#content').append($self_msg);
    };

</script>

 看看结果,个人感觉 还是没那么丑,有点样子的, 哈哈哈。。。

四、那多人聊天室:

  app.py文件里的哦~

# 用来存放多人聊天用户的连接  格式: {用户名 : 连接对象, ...}
conn_user_dict = {}

# 多人聊天室 群聊
@app.route('/ws/<username>')
def ws(username):
    # 获取连接通道
    user_socket = request.environ.get('wsgi.websocket')
    if not user_socket:
        return '请使用websocket连接 '
    conn_user_dict[username] = user_socket
    while True:
        try:
            user_msg_json = user_socket.receive()
            user_msg = json.loads(user_msg_json)
            # 遍历连接对象字典
            for i in conn_user_dict:
                # 如果不是当前连接发送来的消息,就将消息发送给该连接对象
                if not i == user_msg['send_user']:
                    conn_user_dict[i].send(user_msg_json)
        except Exception as e:
            if username in conn_user_dict:
                conn_user_dict.pop(username)
            print(e)
            break

ws.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <style>
        #content {
            width: 100%;
            height: 200px;
            background-color: #e4e4e4;
        }

        #input {
            width: 100%;
            height: 50px;
        }

        .login {
            margin: 15px 0;
        }

        .self_info {
            color: #1004ff;

        }

        .self {
            margin-left: 100px;
        }

        .friend_info {
            color: red;

        }

        .friend {
            margin-right: 100px;
        }

        .friend_msg, .self_msg {
            width: 100%;
        }

    </style>

</head>
<body>
<div class="container">
    <div class="login">
        <div class="form-inline">
            <label for="in_login">用户名</label>
            <input id="in_login" type="text" class="form-control" placeholder="用户名">
            <button id="b_login" type="submit" class="btn btn-default">Sign in</button>
        </div>
    </div>

    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-primary">
                <div class="panel-heading">
                    聊天室
                </div>
                <div id="content" class="panel-body">
                    <div class="friend_msg clearfix">
                        <div class="pull-left friend">
                            <span class="friend_user">对方:</span>
                            <span class="friend_info"> 你好! </span>
                        </div>
                    </div>
                    <div class="self_msg clearfix">
                        <div class=" pull-right self">
                            <span class="self_info"> 你好 </span>
                            <span class="self_user">  : 我</span>
                        </div>
                    </div>
                </div>
            </div>

            <div id="input">
                <textarea id="input-info" class="form-control" rows="3"></textarea>
                <input id="submit" class="btn btn-default" type="submit" value="Submit">
            </div>
        </div>
    </div>
</div>

</body>
<script src="https://cdn.bootcss.com/jquery/3.3.0/jquery.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<script type="application/javascript">
    var ws_url = 'ws://127.0.0.1:9527/ws/';
    var ws = null;
    {#var ws = new WebSocket('ws://127.0.0.1:9527/ws');#}
    {#ws.onopen = function () {#}
    {#ws.send('qweqwe')};#}

    //用户登录名
    var login_user

    //登录:
    $('#b_login').click(function () {
        var user = $('#in_login').val();
        console.log('user', user);
        if (!user) {
            alert('用户名不能为空!!!')
        } else {
            login_user = user
            console.log(ws_url + login_user);
            ws = new WebSocket(ws_url + login_user);

            //接收信息
            ws.onmessage = function (serv_msg) {
                serv_msg = JSON.parse(serv_msg.data)
                console.log('******secv********',serv_msg)
                var friend_info = serv_msg['send_msg'];
                var friend_user = serv_msg['send_user'];
                create_friend_msg(friend_info, friend_user)
            };
        }
    });

    //发送信息
    $('#submit').click(function () {
        var input_info = $('#input-info').val();
        var send_msg_json = {
            send_user: login_user,
            send_msg: input_info
        };
        ws.send(JSON.stringify(send_msg_json));
        console.log(JSON.stringify(send_msg_json));
        create_self_msg(input_info);
        $('#input-info').val('');
    });

    //创建发出信息的标签
    function create_self_msg(input_info) {
        var $self_msg = $('.self_msg').first().clone();
        $self_msg.find('.self_info').text(input_info);
        $self_msg.find('.self_user').text('  : ' + login_user);
        $('#content').append($self_msg);
    };

    //创建收到信息的标签
    function create_friend_msg(friend_info, friend_user) {
        var $self_msg = $('.friend_msg').first().clone();
        $self_msg.find('.friend_info').text(friend_info);
        $self_msg.find('.friend_user').text(friend_user  + '  : ');
        $('#content').append($self_msg);
    };

</script>
</html>
ws.html
原文地址:https://www.cnblogs.com/95lyj/p/9514117.html