第二十二 webchat

Posted ckl893

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第二十二 webchat相关的知识,希望对你有一定的参考价值。

1.聊天框切换

1.1.定义全局字典

        //globe chat record dic
        GLOBAL_CHAT_RECORD_DIC = {
            \'single\':{},
            \'group\':{},
        }

 

1.2.增加归档

 //在切换之前把之前的聊天内容归档
            var current_session_id = $(".chat-box-title").attr("contact-id");
            var current_session_type = $(".chat-box-title").attr("contact-type");
            if(current_session_id){
                GLOBAL_CHAT_RECORD_DIC[current_session_type][current_session_id] = $(".chat-box-window").html()
            }

1.2.获取新内容

            //获取新内容
            var new_contact_chat_record = GLOBAL_CHAT_RECORD_DIC[contact_type][contact_id];
            //如果是第一次从字典取值
            if(typeof new_contact_chat_record == \'undefined\'){
                new_contact_chat_record = \'\';
            }
            //将内容赋予到对话框
            $(".chat-box-window").html(new_contact_chat_record)

1.4.测试切换

 2.消息展现到对话框

2.1.消息解析

  function GetNewMsgs() {
            console.log("--- getting new message ---");
            $.getJSON("{% url \'get_new_msgs\' %}",function(callback){
                console.log(callback);
                ParseNewMsgs(callback);//把新消息进行解析
                GetNewMsgs();
            });//end post
        }

2.2.消息定义

  function ParseNewMsgs(callback) {
          var current_session_type = $(".chat-box-title").attr("contact-type");
          var current_session_id = $(".chat-box-title").attr("contact-id");
            for(var i in callback){
                console.log(callback[i]);
                // { from: "1", to: "5", type: "single", msg: "\\n22", timestamp: 1521081612.0092783 }
                if(callback[i].from == current_session_id && current_session_type == callback[i].type){
                    //此消息的发送方当前正在跟我聊天
                     var msg_item_ele = "<div class=\'msg-item\'>" +
                        "<span>" + callback[i].from + "</span>" +
                        "<span>" + callback[i].timestamp + "</span>" +
                        "<div class=\'msg-text\'>" + callback[i].msg + "</div>" +
                        "</div>";
                     $(".chat-box-window").append(msg_item_ele);
                }//end if
            }//enf for
        }

2.3.测试发送

ckl 向贾岛发消息:

贾岛给ckl回消息:

消息时断时续

3.消息暂存,登录后就接收

3.1.暂存消息到字典

 for(var i in callback){
                console.log(callback[i]);
                // { from: "1", to: "5", type: "single", msg: "\\n22", timestamp: 1521081612.0092783 }
                var msg_item_ele = "<div class=\'msg-item\'>" +
                        "<span>" + callback[i].from + "</span>" +
                        "<span>" + callback[i].timestamp + "</span>" +
                        "<div class=\'msg-text\'>" + callback[i].msg + "</div>" +
                        "</div>";

                if(callback[i].from == current_session_id && current_session_type == callback[i].type){
                    //此消息的发送方当前正在跟我聊天
                     $(".chat-box-window").append(msg_item_ele);
                } else {
                    //消息发送者当前没打开聊天框,消息暂存内存
                    if(GLOBAL_CHAT_RECORD_DIC[callback[i].type][callback[i].from]){
                        GLOBAL_CHAT_RECORD_DIC[callback[i].type][callback[i].from] += msg_item_ele;
                    }else {
                        GLOBAL_CHAT_RECORD_DIC[callback[i].type][callback[i].from] = msg_item_ele;
                    }
                }//end if
            }//enf for

3.2.测试发送

3.2.1.贾岛没有在线的情况下发送

发送消息给贾岛:

 

贾岛不在线:

 

 贾岛收取:

 

 

 4.未读消息数量显示及取消

4.1.未读消息显示

4.1.1.增加新消息提醒

初始状态为隐藏及消息数量为0:

<span class="badge hide">0</span>

新消息提醒:

             //新消息提醒
                //var contact_ele = $(".list-group li[contact-type=\'single\']").filter("li[contact-id=\'3\']")[0];
                var contact_ele = $(".list-group li[contact-type=\'"+ callback[i].type +"\']").filter("li[contact-id=\'"+ callback[i].from +"\']")[0];
                var current_new_msg_num = $(contact_ele).find(".badge").text();
                $(contact_ele).find(".badge").removeClass("hide");
                var ckl = $(contact_ele).find(".badge").text(parseInt(current_new_msg_num)+1);

4.1.2.测试新消息提醒

向贾岛发消息:

接收ckl的消息:

4.2.接收消息后,隐藏消息

4.2.1.隐藏消息

            //将内容赋予到对话框
            $(".chat-box-window").html(new_contact_chat_record)

            //消息接收完毕后,隐藏提醒信息
            var contact_ele = $(".list-group li[contact-type=\'"+ contact_type +"\']").filter("li[contact-id=\'"+ contact_id +"\']");
            $(contact_ele).find(".badge").text(0);
            $(contact_ele).find(".badge").addClass("hide");

4.2.2.测试消息接收后隐藏

发送消息:

接收消息:

 5.群组聊天

5.1.群组展示

5.1.1.前端添加

基本跟用户没有区别,相对应的字段修改为group

     <div role="tabpanel" class="tab-pane" id="group-tab">
                <ul class="list-group">
                    {% for group in request.user.userprofile.group_members.select_related %}
                        <li contact-type="group" contact-id="{{ group.id }}" onclick="OpenChatWindow(this)" class="list-group-item">
                            <span class="badge hide">0</span>
                            <span class="contact-name">{{ group.name }}</span>
                        </li>
                    {% endfor %}
                </ul>
            </div>

5.1.2.显示群组

5.2.群组发消息

5.2.1.修改view,增加group

@login_required
def send_msg(request):
    print(request.POST)
    print(request.POST.get("msg"))
    print(request.POST.get(\'data\'))
    msg_data = request.POST.get(\'data\')
    #如果消息存在
    if msg_data:
        msg_data = json.loads(msg_data)
        #消息增加时间蹉
        msg_data[\'timestamp\'] = time.time()
        #如果消息类型为‘single’
        if msg_data[\'type\'] == \'single\':
            if not GLOBAL_MSG_QUEUES.get(int(msg_data["to"])):
                GLOBAL_MSG_QUEUES[int(msg_data["to"])] = queue.Queue()
            GLOBAL_MSG_QUEUES[int(msg_data["to"])].put(msg_data)
        else:
            group_obj = models.WebGroup.objects.get(id=msg_data[\'to\'])
            for member in group_obj.members.select_related():
                #如果字典不存在这个用户的queue
                if not GLOBAL_MSG_QUEUES.get(member.id):
                    GLOBAL_MSG_QUEUES[int(member.id)] = queue.Queue()
                if member.id != request.user.userprofile.id:
                    GLOBAL_MSG_QUEUES[member.id].put(msg_data)

 5.2.2.前端展示修改

 function ParseNewMsgs(callback) {
          var current_session_type = $(".chat-box-title").attr("contact-type");
          var current_session_id = $(".chat-box-title").attr("contact-id");
            for(var i in callback){
                console.log(callback[i]);

                if(callback[i].type == \'single\'){
                    var msg_from_contact_id = callback[i][\'from\'];
                } else {//如果是group
                    var msg_from_contact_id = callback[i][\'to\'];
                }
                // { from: "1", to: "5", type: "single", msg: "\\n22", timestamp: 1521081612.0092783 }
                var msg_item_ele = "<div class=\'msg-item\'>" +
                        "<span>" + msg_from_contact_id + "</span>" +
                        "<span>" + callback[i].timestamp + "</span>" +
                        "<div class=\'msg-text\'>" + callback[i].msg + "</div>" +
                        "</div>";

                if(callback[i].from == current_session_id && current_session_type == callback[i].type){
                    //此消息的发送方当前正在跟我聊天
                     $(".chat-box-window").append(msg_item_ele);
                } else {
                    //消息发送者当前没打开聊天框,消息暂存内存
                    if(GLOBAL_CHAT_RECORD_DIC[callback[i].type][msg_from_contact_id]){
                        GLOBAL_CHAT_RECORD_DIC[callback[i].type][msg_from_contact_id] += msg_item_ele;
                    }else {
                        GLOBAL_CHAT_RECORD_DIC[callback[i].type][msg_from_contact_id] = msg_item_ele;
                    }
                }//end if

                //新消息提醒
                //var contact_ele = $(".list-group li[contact-type=\'single\']").filter("li[contact-id=\'3\']")[0];
                var contact_ele = $(".list-group li[contact-type=\'"+ callback[i].type +"\']").filter("li[contact-id=\'"+ msg_from_contact_id +"\']")[0];
                var current_new_msg_num = $(contact_ele).find(".badge").text();
                $(contact_ele).find(".badge").removeClass("hide");
                var ckl = $(contact_ele).find(".badge").text(parseInt(current_new_msg_num)+1);
            }//enf for
        }

5.2.3.测试结果

ckl 发群消息:

 

贾岛接收群消息:

 

贾岛回复消息:

贾岛查看消息:

ckl 查看消息:

 5.2.4.用户名展示

 添加用户名字段:

    if (contact_type && contact_id){
               var msg_item ={
                        \'from\': "{{ request.user.userprofile.id }}",
                        \'from_name\':"{{ request.user.userprofile.name }}",
                        \'to\'  :contact_id,
                        \'type\':contact_type,
                        \'msg\' : msg_text
                    };
 if(callback[i].type == \'single\'){
                    var msg_from_contact_id = callback[i][\'from_name\'];
                } else {//如果是group
                    var msg_from_contact_id = callback[i][\'to\'];
                }

ckl 发贾岛信息:

贾岛接收并回消息:

ckl查看:

 6.上传文件

6.1.文件上传添加

6.1.1.添加上传按钮

     <div class="chat-box-emoj">
            <div class="col-md-3">
                <input id="file_upload" type="file">
            </div>
            <div class="col-md-2">
                <span class="glyphicon glyphicon-upload" onclick="FileUpload()"></span>
            </div>
        </div>

6.1.2.ajax post文件

      function FileUpload() {
            var formData = new FormData();
            console.log($(\'#file_upload\')[0].files[0]);
            formData.append(\'file\',$(\'#file_upload\')[0].files[0]);

            $.ajax({
                url:"{% url \'file_upload\' %}",
                type:\'POST\',
                data:formData,
                processData:false,
                contentType:false,
                success:function (data) {
                    console.log(data);
                }
            });//end ajax
        }

6.1.3.增加上传url

from django.conf.urls import url,include
from django.contrib import admin
from webchat import views

urlpatterns = [
    url(r\'^$\',views.dashboard,name=\'chat_dashboard\'),
    url(r\'^msg_send/$\',views.send_msg,name=\'send_msg\'),
    url(r\'^new_msgs/$\', views.get_new_msgs, name=\'get_new_msgs\'),
    url(r\'^file_upload\',views.file_upload,name=\'file_upload\'),
]

6.1.4.增加view方法

def file_upload(request):
    print(request.POST,request.FILES)
    # return HttpResponse(\'dddd\')
    file_obj = request.FILES.get(\'file\')
    new_file_name = "uploads/%s" %file_obj.name
    with open(new_file_name,\'wb\') as new_file_obj:
        for chunk in file_obj.chunks():
            new_file_obj.write(chunk)
    return HttpResponse("-- upload success --")

6.1.5.上传文件

 6.2.增加上传进度条

6.2.1.修改file_upload方法

上传文件,将上传的文件大小写入到一个cache里,另外的方法读取cache内容,来实现上传进度条

from django.core.cache import cache

def file_upload(request):
    print(request.POST,request.FILES)
    file_obj = request.FILES.get(\'file\')
    new_file_name = "uploads/%s" % file_obj.name
    recv_size = 0
    with open(new_file_name,\'wb\') as new_file_obj:
        for chunk in file_obj.chunks():
            new_file_obj.write(chunk)
            recv_size += len(chunk)
            cache.set(file_obj.name,recv_size)
    print(cache.get(file_obj.name))
    return HttpResponse("-- upload success --")

6.2.2.另外的方法读取cache里的内容

def file_upload_progress(request):
    print("----- you meiy --------------------")
    filename = request.GET.get("filename")
    print("this is a name :%s" %filename)
    progress = cache.get(filename)
    print("file[%s] uploading progress[%s]" %(filename,progress))
    return HttpResponse(json.dumps({"recv_size":progress}))

清除cache_key方法:

def delete_cache_key(request):
    cache_key = request.GET.get("cache_key")
    cache.delete(cache_key)
    return HttpResponse("cache key %s delete" %cache_key)

6.2.3.前端获取文件长传进度方法

      function GetFileUploadProgress(file_obj) {
            var UploadProgressRefresh = setInterval(function(callback){
                $.getJSON("{% url \'file_upload_progress\' %}",{filename:file_obj.name},function(callback){
                        console.log("upload progress......" + callback);
                        if(file_obj.size == callback.recv_size){
                            //upload down
                            clearInterval(UploadProgressRefresh);
                            $.get("{% url \'delete_cache_key\' %}",{cache_key:file_obj.name},function(callback){
                                console.log(callback);
                            })
                        }
                        var current_persent = (callback.recv_size/file_obj.size)*100 + "%";
                        $(".progress-bar").css("width",current_persent);
                        $(".progress-bar").text(current_persent);
                })
            },1000);
        }

6.2.4.在ajax上传开始就执行

   function FileUpload() {
            var formData = new FormData();//form table
            console.log($(\'#file_upload\')[0].files[0]);
            formData.append(\'file\',$(\'#file_upload\')[0].files[0]);

            $.ajax({
                url:"{% url \'file_upload\' %}",
                type:\'POST\',
                data:formData,
                processData:false,
                contentType:false,
                success:function (data) {
                    console.log(data);
                }
            });//end ajax

            GetFileUploadProgress($(\'#file_upload\')[0].files[0]);
        }

6.2.5.增加调用的url

from django.conf.urls import url,include
from django.contrib import admin
from webchat import views

urlpatterns = [
    url(r\'^$\',views.dashboard,name=\'chat_dashboard\'),
    url(r\'^msg_send/$\',views.send_msg,name=\'send_msg\'),
    url(r\'^new_msgs/$\', views.get_new_msgs, name=\'get_new_msgs\'),
    url(r\'^file_upload/$\',views.file_upload,name=\'file_upload\'),
    url(r\'^upload_progress/$\',views.file_upload_progress,name=\'file_upload_progress\'),
    url(r\'^delete_cache_key/$\',views.delete_cache_key,name=\'delete_cache_key\'),
]

6.2.6.添加进度条

 <div class="progress">
      <div class="progress-bar" role="progressbar" aria-valuemin="0" aria-valuemax="100" style="width: 60%;">
        60%
      </div>
    </div>

6.2.7.测试上传

 7.发送图片

7.1.增加发送图片方法

function addSentMsgIntoBox(msg_text,msg_type) {
            if(msg_type == \'text\'){
                var new_msg_ele = "<div class=\'msg-item\'>" +
                    "<span>" + "{{ request.user.userprofile.name }}" + "</span>" +
                    "<span>" + new Date().toLocaleDateString() + "</span>" +
                    "<div class=\'msg-text\'>" + msg_text + "</div>" +
                    "</div>"; //用户名+日期+消息内容
            } else if(msg_type.startsWith(\'image\')) {
                var new_msg_ele = "<div class=\'msg-item\'>" +
                    "<span>" + "{{ request.user.userprofile.name }}" + "</span>" +
                    "<span>" + new Date().toLocaleDateString() + "</span>" +
                    "<div class=\'msg-text\'><img width=\'500px\' src=\'/static/" +
                    "{{ request.user.userprofile.id }}/" + msg_text + "\'/></div>" +
                    "</div>"; //用户名+日期+消息内容
            } else {
                 var new_msg_ele = "<div class=\'msg-item\'>" +
                    "<span>" + "{{ request.user.userprofile.name }}" + "</span>" +
                    "<span>" + new Date().toLocaleDateString() + "</span>" +
                    "<div class=\'msg-text\'><a href=\'/static/" +
                    "{{ request.user.userprofile.id }}/" + msg_text + "\' target=\'_bank\'/>点开看看</a></div>" +
                    "</div>"; //用户名+日期+消息内容
            }

7.2.传输文件到用户的id目录下

没有目录,则新建目录

def file_upload(request):
    print(request.POST,request.FILES)
    file_obj = request.FILES.get(\'file\')
    user_home_dir = "uploads/%s" % request.user.userprofile.id
    if not os.path.isdir(user_home_dir):
        os.mkdir(user_home_dir)
    new_file_name = "%s/%s" %(user_home_dir,file_obj.name)
    recv_size = 0
    cache.delete(file_obj.name)
    with open(new_file_name,\'wb\') as new_file_obj:
        for chunk in file_obj.chunks():
            new_file_obj.write(chunk)
            recv_size += len(chunk)
            cache.set(file_obj.name,recv_size)
    print(cache.get(file_obj.name))
    return HttpResponse("-- upload success --")

7.3.测试发送

 

以上是关于第二十二 webchat的主要内容,如果未能解决你的问题,请参考以下文章

python学习手册:第二十二章——模块代码编写基础

第二十二章 模块代码编写基础

第二十二节 with标签使用详解

python学习第二十二章

EasyClick Html UI 第二十二节 jQuery 事件代理

Python之路第二十二篇:轮播图片CSS