Python实现多人在线匿名聊天的小程序

最近看到好多设计类网站,都提供了多人在线匿名聊天的小功能,感觉很有意思,于是基于python的django框架自己写了一个,支持手动实时更名,最下方提供了完整的源码.

在线聊天地址(无需登录,开一个窗口,代表一个用户):

http://zhaozhaoli.vicp.io/chatroom/happy/

移动端聊天效果图:


移动端聊天.PNG

网页版聊天效果图:


网页版聊天.png

实现思路:

  • 发送的消息通过ajax先写入数据库,通过ajax的循环请求,将写入数据库的消息显示到前端界面.

前端核心代码:

<script>

    $(function () {

        $("#send").click(function () {

            var input_info = $("#input_info").val();

            if (input_info.length < 1) {
                alert("请输入字符后发送");
                return;
            } else if (input_info.length > 200) {
                alert("每次发送不可以超出200个字符哈~");
                return;
            }
            else {
                // 获取csrftoken的值
                var csrf_value = $('#csrfmiddlewaretoken').text();
                var user_id = $("#user_id").text();
                var user_name = $("#user_name").text();

                $.ajax({

                    'url': '/chatroom/save_chat_log/',
                    'data': {
                        'chat_content': input_info,
                        'user_id': user_id,
                        'user_name': user_name,
                        'user_ip': '127.127.127.127',
                        'csrfmiddlewaretoken': csrf_value
                    },
                    'type': 'post',
                    'async': false,
                    'success': function (data) {


                    }
                });
                $("#input_info").val("");
                console.log($("#show_info").scrollTop());
            }
        })
    })


</script>


<script>

    var user_id = $("#user_id").text();
    var user_name = $("#user_name").text();

    $(function () {
        var last_id = 0;
        var csrf_value2 = $('#csrfmiddlewaretoken').text();
        function update_info() {
            // ajax 获取最新数据
            $.ajax({
                'url': '/chatroom/get_near_log/',
                'data':{"last_id":last_id,'csrfmiddlewaretoken': csrf_value2},
                'type':'post',
                'async': false,
                'success':function (data) {
                    if (parseInt(last_id) == parseInt(JSON.parse(data.data).last_id)){
                        return;

                    }

                    //获取后台传过来的id值,并将值存储到全局变量中
                    last_id = JSON.parse(data.data).last_id;
                    // 将内容读取,并打印
                    content = JSON.parse(data.data).info;
                    for (var i=0; i< content.length; i++){


                        if (parseInt(content[i].user_id) == parseInt($("#user_id").text())){

                            var html = "<div class='my_info'><span>"+content[i].user_name+"</span></div>";
                            html = html + "<div class='my_one_info'>"+content[i].mess+"</div>";
                            $("#content").append(html);


                        }else{
                            var html = "<div class='other_info'><span>"+content[i].user_name+"</span></div>";
                            html = html + "<div class='other_one_info'>"+content[i].mess+"</div>";
                            $("#content").append(html);
                        }
                        $("#show_info").scrollTop($("#content").height())
                    }
                }
            })
        }
        update_info();
        setInterval(update_info, 1000);
    })
</script>

<script>

    $(function () {

        //监听键盘点击
        $(document).keyup(function (event) {
            if (event.keyCode == 13){
                $("#send").click();
            }
        })
    })
</script>

<script>

    $(function () {

        $("#change_name").click(function () {
            // 获取新名称

            var new_name = String($("#new_name").val());
            // 检查新名称是否合法
            // 如果合法
            if (new_name.length<11 && new_name.length>0){
                console.log(new_name);

                $("#user_name").text(new_name);
                $("#new_name").val("")

            }else{

                alert("昵称长度应为1-10,请重新输入");
                $("#new_name").val("")

            }


        })


    })

</script>


<div id="main_form">

    <div class="my_nike_name">我的昵称:<span id="user_name">{{user_name}}</span><span><button id="change_name">更名</button><input type="text" id="new_name"></span></div>





    <div id="show_info">

        <div id="content">

        </div>
    </div>
    <br>

    <div class="my_nike_name">消息</div>
    <input type="text" id="input_info">

    <button id="send">发送消息</button>

    <div id="user_id" style="display: none">{{user_id}}</div>
    <div id="user_ip" style="display: none">{{user_ip}}</div>

    <span id ="csrfmiddlewaretoken" style="display: none">{{csrf_token}}</span>

</div>




后端核心代码:

# 返回基础页面
def happy(request):

    user_info = UserInfo()
    # 初始用户名为匿名用户

    user_name = "匿名用户"
    user_info.user_name = user_name
    # 利用时间产生临时ID
    user_id = int(time.time())
    user_info.user_id = user_id
    # 获取用户ip
    user_ip = wrappers.get_client_ip(request)
    user_info.user_ip = user_ip
    user_info.save()

    return render(request, 'chatroom/happy.html', locals())

# 保存聊天内容
def save_chat_log(request):
    try:
        print("后端收到了ajax消息")
        chatinfo = ChatInfo()

        # 获取前端传过来的数据
        chat_content = wrappers.post(request, "chat_content")
        user_ip = wrappers.get_client_ip(request)
        user_name = wrappers.post(request, "user_name")
        user_id = wrappers.post(request, "user_id")

        # 将数据存入数据库
        chatinfo.chat_content = chat_content
        chatinfo.user_ip = user_ip
        chatinfo.user_name = user_name
        chatinfo.user_id = user_id

        chatinfo.save()

        return JsonResponse({"ret":0})
    except:
        return JsonResponse({"ret":"保存出现问题"})
        pass


# 获取最近的聊天信息

def get_near_log(request):
    try:
        # 获取数据库内所有的信息
        all_info = ChatInfo.objects.all()

        # 获取数据库内最后一条消息的id
        id_max =ChatInfo.objects.aggregate(Max('id'))
        last_id = id_max["id__max"]
        # print("后台数据库内最新的id为", last_id)

        # 获取请求的id值
        old_last_id = wrappers.post(request, "last_id")
        print(old_last_id,"<-<-")
        print(old_last_id, type(old_last_id),"-->")
        # print("后台发送过来的id为",old_last_id)

        # 返回的信息字典,返回当前时间(current_date),返回信息列表(id_info)

        # 如果第一次请求,则回复最后一条消息的id
        if int(old_last_id) == 0:
            user_ip = wrappers.get_client_ip(request)
            result_dict = dict()
            result_dict["last_id"] = last_id
            result_dict["info"] = [{"id":"-->", "mess":"欢迎"+user_ip+"来到聊天室!", "user_name":"系统消息:"}]
            result_dict["user_id"] = ""
            result_dict = json.dumps(result_dict,ensure_ascii=False)
            # print("第一次握手")
            return JsonResponse({"data":result_dict})

        # 如果数据内没有消息更新
        elif int(old_last_id) >= int(last_id):
            result_dict = dict()
            result_dict["last_id"] = last_id
            result_dict["info"] = [{last_id:"欢迎再次来到聊天室!"}]
            result_dict["user_id"] = ""
            result_dict = json.dumps(result_dict,ensure_ascii=False)
            # print("一次无更新的交互")
            return JsonResponse({"data":result_dict})

        # 如果有消息更新
        else:
            # print("有更新的回复")
            result_dict = dict()
            # 获取新的消息对象集合
            the_new_info =ChatInfo.objects.filter(id__gt=old_last_id)
            # 创建消息列表
            mess_list = list()
            # 将最新的消息组成字典进行返回
            for info in the_new_info:
                # print(info)
                # print ("-->",info.chat_content, info.id)
                # 创建消息字典
                mess_dic = dict()
                mess_dic["id"] = info.id
                mess_dic["mess"] = info.chat_content
                # 将消息所属的用户添加到消息列表
                mess_dic["user_name"] = info.user_name
                mess_dic["user_id"] = info.user_id
                # 将消息字典添加到消息列表
                mess_list.append(mess_dic)


        result_dict["last_id"] = last_id
        result_dict["info"] = mess_list
        # result_dict["info"] = [{"id":3, "mess":"hahah"}, {"id":4, "mess":"666"}]
        result_dict = json.dumps(result_dict,ensure_ascii=False)
        # print("--->>>", type(result_dict))

        return JsonResponse({"data":result_dict})
    except:
        return JsonResponse({"ret":"刷新出现问题"})
        pass

教程涉及到的资源我都通过百度网盘分享给大家,为了便于大家的下载,资源整合到了一张独立的帖子里,链接如下:
//www.greatytc.com/p/4f28e1ae08b1

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,265评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,078评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,852评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,408评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,445评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,772评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,921评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,688评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,130评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,467评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,617评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,276评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,882评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,740评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,967评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,315评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,486评论 2 348

推荐阅读更多精彩内容