February 2011 Archives

OpenParty "梅雪映春"

| 1 Comment
OpenParty "梅雪映春"的准备时间只有7天,却出现了众多水准远超预期,令人惊喜的精彩话题。这还要感谢各位热心的话题贡献者,以及抽出宝贵时间来参加活动的诸位朋友。下面简单记录一下自己现场参与的两个话题。

首先开始的是钱钱带来的《如果做好演讲》。这个话题主要面向对外演讲的技术人员,介绍如何使演讲内容更具吸引力,更易被接受。

做好充足的准备:对外进行的演讲和培训都要在内部先讲上两到三遍。

对于演讲者来说,需要注意的方面:
  • 演讲内容,选择自己擅长的东西
  • 知己知彼,了解参与者的基本情况,他们对于演讲或培训内容的期望(可以直接提问)
  • 不要依赖讲稿,生动的语言可以给听众留下深刻的印象
  • 分享过后将内容总结成脑图,养成良好的知识整理习惯
  • 准备事项Checklist
  • 踩点 - 准时到达会场,尽力避免意外因素
演讲过程中
  • 设计一个足够吸引注意力的开场白
  • 三个要点:
    • 向观众呈现演讲稿梗概
    • 把观众的注意力从幻灯拉回到演讲者身上
    • 用尽浑身解数开始讲故事
  • 忘掉讲稿,一个演讲者首要的任务是讲故事
关于现场氛围的环节

"危机处理"的几种通常方法:
  • 提问 - 引发听众的思考
  • 停顿 - 适当的停顿可以帮助听众理清思路
  • 调侃 - 把严肃的事情换一种方式表达
紧张心理:不要去试图克服,任何人演讲都会紧张,这是一个正常的生理反应。需要让这种反应对演讲起到帮助
  • 不要吃太多肉,适量进食最佳
  • 准备小抄卡片(用到的机会不多但有心理安慰作用);其它工具的辅助,比如Keynote的查看下一页功能
  • 精神胜利法 - 心理暗示
  • 太空漫步法 - 走动一下有助于大脑思考
上面那些技巧,可以帮助你将演讲做得更好 ,却不是让演讲成功的最重要因素。

让演讲成功的两个最重要因素是:
  • Idea, 清晰的、结构化的、内容丰富的信息。
  • 打开那扇门:一次成功的培训和演讲经验,可以帮助演讲者建立感觉和信心
推荐的书籍:

话题结束以后,现场有一位参与者补充分享了一些关于演讲的经验,我认为很有价值,也进行了简要记录。

不用麦克风会有更好的效果:声音可以直达观众耳中。观众听到不自然放大的声音时会产生逃避感,不使用麦克风可以减少距离感,使听众更加认真聆听。实践证明,即使在能容纳500人的会场,通过特殊的发声训练,可以做到不用麦克风进行演讲。

演讲的本质是对话。台下的听众虽然不说话,却是用聆听的形式和演讲者进行交流。所以演讲过程中足够的目光交流很重要。
在偌大的会场上如何更加吸引观众的注意?丰富的肢体动作。思考下戏剧中的演员,在小小的舞台上需要通过鲜艳的装扮以及夸张的肢体语言来放大自己,演讲也是如此。

如何面对现场观众突如其来的挑战?遇到挑战很正常,此时需要演讲者相对强势一些、对自己有足够的信心并建立气场。演讲者应该是控制全场的人,在气势上要压倒对方。演讲时全体听众是演讲者一方的支持者,心理上对于莫名其妙出来挑战的观众并没有好感。


另一个话题是ThoughtWorks徐昊带来的《8小时用HTML5打造VNCViewer》。这个分享非常精彩,其实现过程中的思考方式、使用的新技术都让人有醍醐灌顶的感觉。以下的记录由现场的笔记总结而来,比较粗略,难免有失误,还望大家指正。

由于HTML5具备Canvas, WebSocket,所以萌生了使用HTML5来打造一个VNCViewer的想法。同时为这个项目设定目标:在12小时之内完成。

HTML5的定义

在HTML5之前,HTML这个概念仅指代用以描述数据的语意化文档标签。之前的W3C始终将HTML定位为单纯定义数据的标准,有意淡化BOM(Browser Objective Model)对象。而从HTML5开始,第一次将HTML的概念扩展到HTML+CSS3+JS的集合。在原先的数据表现上添加了一些新的语意化标签如<header>, <footer>等,但BOM的增强更令人兴奋:引入Canvas, WebSQL, WebSocket(在频繁交互的网络应用中节约大量资源), PostMessage(在不同页面之间传递数据)等对象为实现更多种应用提供了可能。

个人项目也要按照标准的项目流程做计划:进行任务分解。有任务分解列表的同时,也要有项目的风险列表。考虑到一些通常的项目风险,比如:一旦协议太复杂以致于不能用很短的时间了解,就会影响项目实现。

首先需要了解VNC协议,任务预计需要两小时。发现VNC的工作原理并不复杂:服务器和客户端经过握手确定协议版本、所支持的编码方式等,随后开始通信,传输屏幕上的显示内容。显示内容传输时支持不同编码方式,协议本身可以扩展以支持更多种编码方式。VNC的协议有43页(链接),1小时阅读完毕。其中主要包括两大部分,显示和接受输入。出于应用需要,不考虑输入部分的实现。

此时任务列表更新为:
  • 建立连接
  • 服务器与客户端间进行握手
  • 开始传送数据
使用HTML5的WebSocket建立连接时,发现WebSocket要求需要HTTP协议才能建立连接;同时建立长连接还需要如下步骤:HTML5端会发送一个请求,询问服务器是否能将协议升级成为WS/WSS协议,服务器需回复确认。但VNC服务器诞生较早,不支持升级协议这个约定。有两种解决方法:自己实现一个VNC Server,或者写一个Proxy来解决问题。因为自己实现VNC Server成本太高,不可能在时间限制内完成,所以选择了写Proxy的方案。
Proxy使用node.js , 一个运行在服务器端的JavaScript框架来完成。起初选用的原因主要还是个人的兴趣,接下来可以看到,最终这个框架拯救了整个项目。这个Proxy只用了10行JavaScript,使服务器和客户端的两个TCP流对接上即可。

服务器端代理部分耗时45分钟

接下来面临的是编码问题,VNC使用底层数据编码,而HTML端是相对高层的数据编码方式,这里通过node.js实现统一;服务器建立连接需要认证,VNC的认证机制使用DES加密。在网上寻找JavaScript DES库的时候,发现能找到的三个库均不能正常工作。不得已自己实现了JavaScript的DES库,耗费了不少时间。此时5个小时过去了,服务器端和客户端已经可以正确连接。

接下来解决显示的问题

Canvas有一个绘制函数几乎可以原生支持VNC的Raw编码方式,于是直接使用这个方法实现。测试时发现基本不能正常使用:由于数据传输量非常大,客户端的性能完全不能满足需求,画图速度太慢,占用资源过高。

6个小时过去了

考虑在信息传输方式上做优化,传递每个像素数据的Raw编码方式所需数据量过大。同时实验中发现不同VNC服务器发送信息的行为不太一样:苹果的服务器按照行的方式发送屏幕显示数据,而某个版本Linux中则是直接把屏幕分为四个区域来处理显示更新。按照区块刷新的编码方式进行了测试,发现并不能解决问题:画面后面的帧显示比原先略快但仍不可用,并且显示第一帧画面的速度非常慢。

解决传输数据量的问题,需要从传输协议上入手。VNC协议默认有5种Encode方式,分别是:
  • 全屏更新
  • 区域刷新
  • Hextile(将屏幕分成16x16的诸多小块来进行刷新,详解
  • zlib 将raw的数据进行压缩然后再传输
  • hextile+zlib,将Hextile格式的数据进行压缩再传输
参考一些资料,均推荐使用zlib方式对数据进行压缩处理,可以节省带宽、提高速度(未经压缩的画面一帧的流量是4.3M)。此时需要一个JavaScript的zlib实现来进行解码工作。发现没有这样的库...... 此路不通。

能否使用HTML5的Worker进行后期处理?查阅文档发现Worker进程不能直接访问DOM对象,所以不能在Canvas上面进行绘画。而且传递大数据量时速度很慢。简单地说这个功能适用于计算密集的任务,但不适合这种数据密集的任务。

最后解决问题的关键功能,是一个比较陈旧、平时几乎不再使用的浏览器功能 - DataURI Encoding。即把资源经由Base64编码后直接显示在页面中。这里面最重要的突破在于:从最终目的中思考,用户最终的目的是什么?所需的VNC解码内容和哪些浏览器支持的原生信息格式最为接近?
首先想到的答案是视频,但是发现如果使用HTML5的<video>标签需要把VNC流转换为视频格式。这个工作太复杂,几乎无法完成。
如果不能作为视频来处理的话,那么作为图片显示的方式是否可行呢?把VNC的数据流转化为图片,浏览器即可通过硬件加速来显示图片。将VNC流转换成相应的图片格式在客户端进行太复杂,同时非常消耗资源。这时之前在服务器端选用的node.js技术发挥了重要作用。在VNC服务器端编写了一个新的VNC编码方式,可以直接将VNC的数据流以JPEG的方式进行编码(解决了传输数据量的问题),然后在服务器的node.js端对数据流进行解码,直接向浏览器传回通过Base64编码的JPEG图片,即可做到以很低的延迟显示VNC服务器的内容。

至此,整个项目完成,共耗时8小时23分钟