zoukankan      html  css  js  c++  java
  • 做一个群组聊天页面

    要做个群组聊天的页面,参考微信的web版本,大致就是分为左右两列,左边是群组列表,右边是群组中的对话

    示例图如下:

    这个页面风格是使用ACE做的,再次啧啧下,ACE真TMD强大,这个页面的风格很招人喜欢。

    做这个页面刚开始的时候我走了弯路,初步想的是使用iframe,左侧群组聊天页面是页面加载的,右侧的群组对话框是个iframe。然后点击左侧的任意一个群组,右侧的对话iframe就修改src,然后更新对话的时候也超简单,直接iframe重新加载一下就ok了。

    但是呢,后来发现,我这样需要写的controller反而更多,一个iframe的controller,一个页面本身的controller,然后在两个iframe需要传递一些东西,特别是群组id。最大的困难就是更新,当我在iframe中发了一条消息之后,iframe中的条目能很快更新,但是外面的页面(由于是使用轮询)就没办法及时更新了。

    后来总结了下,我整个页面就使用最统一的方式,html+jsonp的形式,使用一个页面controller,然后每个行为触发一个jsonp,整体做下来,结果就是js量极速增大。但是,不算坏事。

    页面逻辑是这样:

    首先页面初始加载群组列表

    其次点击群组名称,同步加载出现右侧的对话框。注意这里是使用同步加载。因为从用户体验上,如果使用异步,点击了群组却没有出现对话框,会有bug的感觉。jquery的ajax是有提供jsonp和同步调用的:

    代码:

    $("[name=talk_talk]").click(function(event){
        event.preventDefault();
    
        var target = event.target;
        var mgid = $(target).attr("data-mgid");
        var action = "http://api.test/group/messageList"
        var params = "mgid=" + mgid;
    
        $.ajax({
            type: "get",
            dataType: "jsonp",
            async:false,
            url: action,
            data: params,
            jsonp: 'callback',
            jsonpCallback: 'callback231',
            success: function(data) {
                if (data.msg == 'ok') {
                    var messages = data.messages;
                    var users = data.users;
                    var message_contents = '';
                    for(var i=0; i< messages.length; i++) {
                        var message = messages[i];
                        var sid = message.sid;
                        var sender = users[sid];
                        message.sender = sender;
                        message_content = getDialogHTML(message);
                        message_contents = message_contents + message_content;
                    }    
                    $("#messages_show").html(message_contents);
                    $("#messages_show").attr("cur_mgid", mgid);
                    $("#group_unreadflag_" + mgid).hide();
                    $("#widget-box-dialog").show();
                }
            }
        });
    });

    这里的ajax的dataType设置为jsonp表示是个jsonp请求,加上后面的jsonp和jsonpCallback,表示调用的时候我传递的请求带上了callback=callback231。

    这里的jsonpCallback也是可以不写的,但是如果不写jquery会使用形如:callback_321342_324123这样的函数名来替换。但是我希望服务器端使用白名单机制来控制callback只能是字母和数字(Yii):

    if (!empty($callback) && ctype_alnum($callback)) {
        echo "{$callback}(" . CJSON::encode($ret) . ")";
        Yii::app()->end();
    }

    所以我就手动设置了callback函数。相关的安全考虑我记得以前有一篇文章写过:http://www.cnblogs.com/yjf512/p/3222269.html

    ajax的默认是异步的,所以要设置同步的话需要设置async:false。

    接着就是轮询函数

    服务端有个jsonp接口能根据我返回的最新时间,返回这个时间后我收到的所有群组消息。

    代码几乎同上,不同的就是这个行为应该且必须是异步的。然后做两个事情:一件事情是如果左侧的群组有新消息,设置一个标志表示有新消息。另一个事情是如果右侧的对话显示的是当前这个群组的对话,就增加一个最新的消息放到上面。

    然后是发送消息,基本同上。

    好吧,主要还是秀一下ACE模板,看的爽。

  • 相关阅读:
    一个简单的knockout.js 和easyui的绑定
    knockoutjs + easyui.treegrid 可编辑的自定义绑定插件
    Knockout自定义绑定my97datepicker
    去除小数后多余的0
    Windows Azure Web Site (15) 取消Azure Web Site默认的IIS ARR
    Azure ARM (1) UI初探
    Azure Redis Cache (3) 创建和使用P级别的Redis Cache
    Windows Azure HandBook (7) 基于Azure Web App的企业官网改造
    Windows Azure Storage (23) 计算Azure VHD实际使用容量
    Windows Azure Virtual Network (11) 创建VNet-to-VNet的连接
  • 原文地址:https://www.cnblogs.com/yjf512/p/3782587.html
Copyright © 2011-2022 走看看