• 1. (本页无文本内容)
  • 2. WEBIM项目经验总结梁栋 2011.04.29
  • 3. 起源2011年,那是一个春天,有一个公司,又开始在画一个圈。
  • 4. 起源互联网有一个时代是属于社交网站的
  • 5. 起源互联网有一个地盘是属于中国的
  • 6. 起源关系是用户粘性的重要来源!
  • 7. 来而不往非礼也,竞争不是一个人说了算的。
  • 8. 我们的打算,利用一下这个功能的接口。
  • 9. 采用已经有一定积累的技术。最终管这个叫做:微通信。
  • 10. HTTP是半双工的 HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种“短连接” 轮询(polling),每隔几秒向服务器请求更新数据 长轮询(long polling),模拟全双工的通信(Comet)
  • 11. 基于 Iframe 及 htmlfile 的流(streaming)方式, 通过在 HTML 页面里嵌入一个隐蔵帧,然后将这个隐蔵帧的 SRC 属性设为对一个长连接的请求,服务器端就能源源不断地往客户端输入数据。不足之处:IE、Firefox下端的进度栏都会显示加载没有完成,Chrome上方的图标会不停的转动。一个称为“htmlfile”的 ActiveX 可以解决 IE 中的加载显示问题,但是其他浏览器暂无解决方法
  • 12. 普通Ajax请求ServerBrowsertime linerequestrequestdatadata需要返回的数据需要返回的数据
  • 13. Long pollServerBrowsertime linepollpolldatadata没有需要推送的数据有需要推送的数据没有需要推送的数据有需要推送的数据n久之后...收到数据后再次发起poll收到数据后再次发起poll
  • 14. Dojo 的创始人 Alex Russell 最开始提出“Comet”这个词。Dojo 基金会提出了 Bayeux 协议用来标准化 Comet 应用中客户端和服务器端之间的通信。关于 Bayeux 协议的具体信息,请看 Bayeux介绍。Dojox.cometd 实现了 Bayeux 协议的客户端部分,使用 HTTP 长轮询来作为数据的传输通道。 Comet中文介绍 http://www.ibm.com/developerworks/cn/web/wa-lo-comet/ http://www.ibm.com/developerworks/cn/web/wa-lo-w2fpak-comet/ Bayeux介绍 http://svn.xantus.org/shortbus/trunk/bayeux/bayeux.html#toc_17
  • 15. 用JSONP传输数据,基于Bayeux 协议的数据传输格式。 下面是客户端第一次的请求与服务端的返回
  • 16. 通过三次握手确保连接成功,然后获取数据
  • 17. 初始化数据:
  • 18. Script标签被插入到了iframe里面,所以能看到回调的格式为: parent.org.cometd.script._callback2&1304402387361 使用的插件是一个兼容长连接的组件。里面有使用IE的ActivexObject: htmlfile 。 Channel区分了基本接口类型。Type区分了请求的数据类型。 在发生异常时,advice提供了服务端与客户端的机制,可以让客户端根据服务端传来的信息进行下一步操作。
  • 19. 软件开发过程 —— ScrumScrum是一种迭代式增量软件开发过程,通常用于敏捷软件开发。Scrum在英语的意思是橄榄球里的争球。 虽然Scrum是为管理软件开发项目而开发的,它同样可以用于运行软件维护团队,或者作为计划管理方法:Scrum of Scrums. http://zh.wikipedia.org/wiki/Scrum Scrum定义了许多角色,根据猪和鸡的笑话分为两组,猪和鸡 一天,一头猪和一只鸡在路上散步,鸡看了一下猪说,“嗨,我们合伙开一家餐馆怎么样?”,猪回头看了一下鸡说,“好主意,那你准备给餐馆卖什么呢?”,鸡想了想说“餐馆卖火腿和鸡蛋怎么样?”,“我不这么认为”,猪说,“我全身投入,而你只是参与而已”。 挺冷的……
  • 20. 产品负责人Scrum主管(或促进者)开发团队用户利益相关者(客户,提供商)经理
  • 21. 在冲刺中,每一天都会举行项目状况会议,被称为“scrum”或“每日站立会议”。每日站立会议有一些具体的指导原则: 会议准时开始。对于迟到者团队常常会制定惩罚措施(例如罚款,做俯卧撑,在脖子上挂橡胶鸡玩具) 欢迎所有人参加,但只有"猪"可以发言。 不论团队规模大小,会议被限制在15分钟。 所有出席者都应站立。(有助于保持会议简短) 会议应在固定地点和每天的同一时间举行。Scrum会议
  • 22. Scrum会议在会议上,每个团队成员需要回答三个问题: 今天你完成了那些工作? 明天你打算做什么? 完成你的目标是否存在什么障碍?(Scrum主管需要记下这些障碍) 每一个冲刺完成后,都会举行一次冲刺回顾会议,在会议上所有团队成员都要反思这个冲刺。举行冲刺回顾会议是为了进行持续过程改进。 会议的时间限制在4小时。
  • 23. 冲刺订单冲刺订单(sprint backlog)是大大细化了的文档,包含团队如何实现下一个冲刺的需求的信息。 任务被分解为以小时为单位,没有任务可以超过16个小时。 如果一个任务超过16个小时,那么它就应该被进一步分解。 冲刺订单上的任务不会被分派,而是由团队成员签名认领他们喜爱的任务。 一个任务分为todo ,开发中,自测,提交测试,完成几个阶段。
  • 24. 冲刺订单
  • 25. 燃尽图
  • 26. 燃尽图
  • 27. 实施白板
  • 28. Scrum实施感想充分发挥了成员的特点,有人开发速度快,有人熟悉某项技术,成员根据自己的喜好与优势选择任务,这个很重要。 Scrum会议的督促作用非常明显,但也会给成员带来相当的压力。 Scrum主管有必要注意排解成员压力。 燃尽图后期的陡峭往往说明了任务分割与时间估算的不完善。但是有时这不可避免,可以考虑用完成度百分比乘以工作任务,或者将任务分阶段(将预备阶段,开发阶段与测试阶段分开)来平缓燃尽图曲线,达到更细致描绘工作进度的目的。 Scrum主管开发的时间可能不会很多,一般来说也不适合参与开发,因为排解外部干扰,解决项目组障碍都会花去很多零碎时间进行沟通以及其他事务,都会干扰个人的正常开发。建议不要让开发主力担任Scrum主管,应当由擅长沟通,有较深技术底蕴,对产品比较熟悉或者理解深刻的人员担任。 项目开发正式开始前,必须达成必要的开发共识,必须完成基本的开发约定。每个人并不是只维护自己的代码。 项目开发开始前的会议不要过长,主要确定方向,任务与最关键的技术细节。应提供一个技术预备期供大家分享要使用的技术知识或者制定开发规范。
  • 29. NameEventsExtends Property_$eventsMethodsaddEvent removeEvent addEvents removeEvents fireEvent  SP0.25 NameBaseExtendsEventsProperty Methods   SP0.25 NamePanelExtendsBasePropertyrootMethodsrender _initComponentSP1 IM基本组件
  • 30.    IM基本组件NameUserExtends Propertynick, status, vipFlag, unreadMsgCount, uid, avatarMethodsrecieveMsgHandler updateUnreadCount createMiniUser createCompeleteUser createChatUser  SP2NameMiniUserExtends Propertyroot, userMethodsupdateUnreadMsgCount _changeStatus changeStatus2Free changeStatus2Busy changeStatus2Offline flash4NewMsg render bindEvent  SP0.5NameCompeleteUserExtends Propertyroot, userMethodsshowUnreadMsgCount hideUnreadMsgCount _changeStatus changeStatus2Free changeStatus2Busy changeStatus2Offline flash4NewMsg render bindEvent  SP1NameChatUserExtends Propertyroot, user, content, closeBtnMethodsshowUnreadMsgCount hideUnreadMsgCount _changeStatus changeStatus2Free changeStatus2Busy changeStatus2Offline flash4NewMsg render bindEvent   activeUser recoverUser remove  SP2
  • 31.    IM基本组件NameContactsWindowExtendsPanelPropertyroot, searchBar, groups, statusManagerMethodsrender bindEvent show hide  SP0.5NameStatusManagerExtends Propertyroot, StatusTextNode, statusIconNode, statusListNodeMethodsrender, changeStatus2free changeStatus2offline changeStatus2busy bindEvent showStatusListNode hideStatusListNode  SP0.5NameUserGroupExtends PropertyuserCount groupName hideFlag userListMethodsgetUserCount updateUserCount showUsers hideUsers addUser removeUser  SP1NameSearchBarExtends PropertysearchInput, suggestorMethodsrender search updateResult2Container showResult hideResult bindEventSP最简: 1 完整:2
  • 32.    IM基本组件NameChatWindowExtendsPanelPropertyroot, chatUserCountNode, chatUserGroup, chatContentGroup, msgEditor, msgToolBarMethodsrender _bindDomEvent _bindDataEvent show close upadateChatUserCount hide2Pop  SP1.5NameChatUserGroupExtends Propertyroot, userList, upBtn, downBtnMethodsrender bindEvent scrollUp scrollDown addUser removeUser  SP1NameMsgEditorExtends Propertyroot, contentNode, sendBtn, countTipNode,  Methodsrender, send, overCountHandler normalCountHandler flashContentNode addPhiz  SP2NameChatContentExtends PropertyrootMethodsrender addUserMsg addSysMsg show hide remove  SP2NameChatContentGroupExtends Propertyroot, MethodsaddChatContent removeChatContent  SP0.5
  • 33.    IM基本组件NameMsgToolBarExtends Propertyroot, phiz, historyMsgMethodsrender  SP0.5NameHistoryMsgExtends PropertyrootMethodsbindEvent, render  SP0.5NamePhizExtends Propertyroot, phizBoxMethodsrender bindEvent addPhiz2MsgEditor showPhizBox hidePhizBox  SP2
  • 34.    IM基本组件
  • 35. 开发文件
  • 36. 使用jQuery 使用插件 DynamicLoad 加载JS。在loader.js 中配置JS文件与加载顺序 定义一个命名空间管理代码 用 Class 插件构建模块,实现继承与封装 构建 Events 机制,解耦模块 构建专门的数据模块管理变更频繁的数据。 达成的开发共识
  • 37. 基础架构服务器IODATAUIUI COREEvents
  • 38. 简易命名空间管理
  • 39. 一些扩展
  • 40. 自定义事件模型 addEvent addEvents fireEvent removeEvent removeEvents
  • 41. 全局监听举例WBIM.UI.ChatContentGroupWBIM.UI.ChatUserGroup
  • 42. 全局监听举例WBIM.UI.HistoryMsgWBIM.UI.MsgEditor
  • 43. 新版新浪包有类似的组件STK.core.util.listener ---- 广播/** * 事件广播类 * @id STK.core.util.listener * @author FlashSoft | fangchao@staff.sina.com.cn * @version 1.0 * @example * STK.core.util.listener.register('topBar', 'popup', function(a, b) {console.log(a, b)}); * STK.core.util.listener.fire('topBar', 'popup', [1, 2]);// print 1, 2 * * STK.core.util.listener.register('topBar', 'popup', function(a, b) {console.log(a, b)}); * STK.core.util.listener.fire('topBar', 'popup', [[1, 2]]);// print [1, 2], null */ STK.register('core.util.listener', function($){ return (function(){ var dispatchList = {}; var topWindow;
  • 44. /** * 自定义对象事件 注意:使用属性 __custEventKey__ 污染自定义对象 * 事件添加或绑定前应该先定义事件,定义事件方法为 custEvent.define(obj, type) * 约定:事件处理函数的第一个参数为event对象其结构为: * { * type:"click",//{String}绑定时的自定义事件类型 * data:{}//{Any}绑定时的扩展属性 可以是任意类型 * } * @id STK.core.evt.custEvent * @author Finrila|wangzheng4@staff.sina.com.cn * @version 1.0 * @example * var a = {}; * var f = function(event) { * console.log(event.data); * console.log(event.type); * console.log(arguments[1]); * }; * STK.core.evt.custEvent.define(a, "click"); * STK.core.evt.custEvent.add(a, "click", f,{aaa:0}); * STK.core.evt.custEvent.fire(a, "click", 5); * STK.core.evt.custEvent.fire(a, "click", 33); * STK.core.evt.custEvent.remove(a, "click", f); * STK.core.evt.custEvent.fire(a, "click", 22); * STK.core.evt.custEvent.remove(a, "click"); * STK.core.evt.custEvent.remove(a); * STK.core.evt.custEvent.undefine(a, "click"); * STK.core.evt.custEvent.undefine(a);
  • 45. 多页面同步需要在多个页面部署webim 用户打开的多个页面,未读消息数量,操作状态应当同步 用户页面跳转,未读消息数量,操作状态应当保留 降低服务器压力,多个页面只使用一个与服务端的连接。 兼容各版本浏览器
  • 46. 浏览器调查
  • 47. 需要一个同步方案 —— 推还是拉 ? Flash LocalConnection 页 面上的双向通信也可以通过Flash来解决,Flash API中有LocalConnection这个类,该类允许两个SWF之间通过进程通信,这时SWF可以播放在独立的Flash Player或者AIR中,也可以嵌在HTML页面或者是PDF中。遵循这个通信原则,我们可以在不同域的HTML页面各自嵌套一个SWF来达到相互传递 数据的目的了。SWF通过LocalConnection交换数据是很快的,但是每次的数据量有40kb的大小限制。 需要持久存储 —— localstorage / userdata 数据分发,主从切换 多页面同步
  • 48. 服务器IOUI CORE主SYNCIOSYNCUI CORE从主 主从切换与页面同步
  • 49. 各种问题与解决方案
  • 50. 同步事件同步模块 Sync 继承自 Events 封装与swf的交互 加上延时判断flash是否成功加载。 没有flash参与时就是一个普通的中转模块
  • 51. 模拟流传输初始化用户数据,表情数据,轻松超过40K,如何传输? 模拟流传输 1,将数据编码 2,分拆数据,打上标记,记录包数量,按顺序发送 3,接收端缓存分拆的数据,合并分拆的数据 4,解码 小心 —— encodeURIComponent 效率很低。用escape代替。 Flash内部实现
  • 52. localstorage 与 userdataHtml5组件localstorage,存储限制:>=5M 支持localStorage的浏览器:IE 8+, Firefox 3.0+, Safari 4.0+, Chrome 4.0+, Opera 10.5+。 IE专用userdata,存储限制:128K(受限制站点64K) Userdata 跨路径无法存储(IE6) 方案1:用iframe 方案2:改用flash so(share object) 存储限制:20K
  • 53. 传输这种字符串: 浏览器报错 解决方案: escape/unescape flash传输报错
  • 54. 内存泄露Iframe未释放引起内存泄露 插入的script元素上面绑定的事件引起的内存泄露 使用beforeunload 还是 unload 释放资源 script元素上无法移除的事件(诡异) 用 swfobject.getObjectById(swfObjID) 访问swf对象
  • 55. 被误触发的beforeunloadjavascript:; 与 javascript:void(0);
  • 56. 被误触发的beforeunloadFF运行结果: 2,3,1 IE运行结果:2,3,’unload’,1 IE下的beforeunload事件会被触发 解决方案:加上onclick=“return false;”,则href中javascript:后面的代码不会执行(默认行为被阻止)。
  • 57. 获取textarea光标位置
  • 58. 获取textarea光标位置
  • 59. 获取textarea光标位置
  • 60. 图片延迟加载
  • 61. 图片延迟加载
  • 62. 批量渲染
  • 63. 内存控制
  • 64. 内存控制
  • 65. Q & A
  • 66. (本页无文本内容)