Python實現多人線上匿名聊天的小程式

木子昭發表於2017-11-29

最近看到好多設計類網站,都提供了多人線上匿名聊天的小功能,感覺很有意思,於是基於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

教程涉及到的資源我都通過百度網盤分享給大家,為了便於大家的下載,資源整合到了一張獨立的帖子裡,連結如下:
http://www.jianshu.com/p/4f28e1ae08b1


相關文章