第二十二 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的主要内容,如果未能解决你的问题,请参考以下文章