• 做一个群组聊天页面


    要做个群组聊天的页面,参考微信的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模板,看的爽。

  • 相关阅读:
    C语言中do...while(0)用法小结
    C语言函数指针的用法
    C语言预处理命令之条件编译
    欧拉计划11-15题
    欧拉计划6-10题
    已加载“C:WindowsSysWOW64 tdll.dll”。无法查找或打开 PDB 文件。
    C++使用SQLite步骤及示例
    linux 安装sysstat使用iostat、mpstat、sar、sa
    Nmon命令行:Linux系统性能的监测利器
    linux服务器性能检测工具nmon使用
  • 原文地址:https://www.cnblogs.com/yjf512/p/3782587.html
Copyright © 2020-2023  润新知