竹磬网-邵珠庆の日记 生命只有一次,你可以用它来做些更多伟大的事情–Make the world a little better and easier


277月/170

时间和金钱的思考

发布在 邵珠庆

富人会寻找最卓越的、合适的人帮助他们完成目标中的各项任务,花钱请最专业的、效率最高的人帮助他们完成他们并不最擅长的事。比如,管理,投资,创业,教育等等。

穷人倾向于用最省钱但也可能是最费力的方法完成一件他们也许并不擅长的事。

为什么?

1、)哪种资源越稀缺,认知就越可能过度关注那种资源,而导致判断力下降,决策质量下降。

穷人缺钱,容易过于看中钱,而忽略其他比钱更重要的,同样是可利用的资源(人,思维,创意,文化等等)。

2、)所具备的资源组合会一定程度限制目标设定和战略计划,以及特殊能力的发展。

穷人缺钱,就难免因为缺钱而思维受限,思路狭隘,也许有点小钱的就会以赚点小钱作为目标,又也许固化了穷的习性和习惯,难以进入追求理想和财富的上升循环。

3、)文化、教育背景塑造的思维方式不同,经历与成长方式的不同,价值判断、认知体系不同,态度与行为自然不同。

人生对每个人都是开放的,并非富是终极目标,穷也未必是可耻的,因为穷富不过是相对的概念,不代表具体的处境。

只能说很多表面现象(譬如富人为何富,穷人为何穷)都有独特的起源,那起源受一个人的文化、教育背景的影响,更根植于个人的经历、认知和成长,最终个人所得及个人境遇,不过是每个人追求理想人生的副产品。

许多年轻人奋斗的唯一目标,就是早日实现财务自由。但是财务自由的本质并不是钱多到花不完,而是终于可以从每天靠消耗时间来换取金钱这个阶段抽离出来。又或者说,实现财务自由的人,是找到了一个渠道,并在这个渠道上建立了一个相对完善的系统,这个系统在离开了他本人之后,依旧可以正常运转并获得收益。从而,解放了他的生命和时间。这有点像是发现了一口井,然后找来几个人负责打水卖水,然后给这几个打水的人发放收入一样。

有一个悖论其实非常有趣,就是说我们在谈论收入时,往往没有谈及时间投入。比如说A收入是五千,但是每天只需要工作一两个小时;而B收入是一万,但是每天却需要工作十个小时以上。从绝对值上,B收入是A的一倍,但是从性价比上,B简直是太不划算了。因为人的生命和时间是无价的,而B却把它卖的如此廉价。更可惜的是,每天的时间又是固定的,如果按照B这样用生命换钱,那么他的一生就会陷入一个怪圈:像机器一样运转,损耗自己,换取收入。

对于金钱的获取和支配,对于所有普通人而言,都是与常识相反的逻辑怪圈。如果不能早些顿悟并跳出圈外,那么终其一生,都将被碌碌无为所困扰。

217月/170

孩子注意力训练

发布在 邵珠庆

孩子如果注意力越集中,学习效果越好。因为当孩子在专心学习的时候,大脑就会把这些新的信息映射到已知的内容上,从而构建新的神经联结。反之如果孩子走神了,就记不住正在学习知识,导致孩子学习效果不好成绩差。

所以脑电训练网提醒家长,孩子注意力不集中不仅仅是只影响学习而已。比如人际关系紧张、学校纪律难约束、自理自立能力差、自信心不足等等都会受到影响的...

那么,到底该如何解决孩子注意力不集中这个大难题?家长可以让孩子这样训练:

1. 仔细看。仔细看的游戏是为了训练孩子的视觉注意。仔细看的游戏包括,拼图游戏,例如动物拼图,水果拼图,人物拼图,地图等。这样的拼图游戏需要宝宝耐心参与,参与组合。家长可以根据幼儿的年龄阶段选择适合的拼图,2~3岁的拼图最好在4片之内,3~4岁的最好在8片之内,4~6可以在12片左右。

2. 仔细听。仔细听的游戏是为了训练孩子的听觉注意。仔细听的游戏,例如传话游戏。家长可以玩这个小游戏,可以由妈妈说一句话,传给爸爸,再传给宝宝,最后,让妈妈和宝宝说一说自己听到的。这个游戏非常有趣,而且需要在耳边低语,促进宝宝注意力的发展非常有效。

3. 抑制训练。抑制训练的游戏是为了抑制孩子的多动冲动的表现。抑制训练的游戏,包括顶板游戏,头顶顶一个塑料板,脚尖贴脚跟的从规定的地方走到另一个地方,中途板不能掉。

4. 运动训练。运动训练包括肢体大运动和手部精细运动,是为了锻炼孩子骨骼肌肉的发展和手指的灵活度的。肢体大运动的包括跑跳钻爬,例如单脚跳,双脚跳,老鹰捉小鸡等等;手部精细运动,包括串珠子,捏橡皮泥,折纸,做手工等等。

217月/170

可以不优秀但不能没教养

发布在 邵珠庆

一个孩子的教养是成功的基本因素,而教养是从小就要开始培养的,是父母的家庭教育方式影响的。因此,在孩子成长的每一步,都需要关注孩子的教养问题。

当你带着孩子出门,给孩子带上小书包、小水壶的时候,别忘了给他带上教养。有教养的人在哪里都会受到尊重,而没教养的样子,真的很丑。

1、这个故事告诉你,孩子为何会缺乏教养

周末,几个朋友在饭店吃饭,旁边一桌坐着两个家庭聚餐,都是六七岁的孩子,一会拿筷子敲碗制造噪音,一会满店乱跑乱追逐打闹。

周围的人因为影响了进餐而纷纷侧目,他们的父母都忙着聊着家长里短,并不在意。

服务员上菜时,其中一个孩子将菜汤泼到服务员身上,事后坦白就是为了好玩,服务员对此非常生气。

这时孩子的母亲不仅没有歉意反而埋怨道:“哎呦,你下班洗洗不就行了么,折磨大人了怎么还跟孩子一般见识”,转头对孩子说,“你不好好学习将来就像她一样,当个服务员。”

这位母亲出门之前,肯定忘了给孩子带上教养,因为她本身也没有这样的东西。

在缺乏教养的人身上,都有着一样的共同点:以自我为中心,粗暴当作勇敢、愚昧当作学识、可笑当作幽默,口无遮拦当作随性直爽。

2、教养决定了一个人飞得远不远

辰辰班上有个同学,是一个残疾的小男孩,天生并不灵敏。除了身体上的缺陷之外,似乎大脑的发育和接受新事物的能力也比较弱。他每一次考试都是班级最后几名。

可是,他却是班上人缘最好的。在学校里,他有很多朋友,外出秋游的时候,总是有很多同学争先恐后想帮他推轮椅,每到他生日,有很多同学给他礼物,他们邀请他去参加同学的生日聚会。为什么?

他对谁都很礼貌

他懂得爱人也爱己,他懂得接受时礼貌,拒绝时也彬彬有礼。

他为人不贪心

不贪心别人对他的爱,不贪心别人的玩具,他不会觉得自己残疾而应该享受更多的爱,他常常一跛一跛地去集体活动,和那些快迟到了的同学说,没事,我自己慢慢过来就成。他知道自己应该得多少,也知道别人应该得多少。

他懂得分享

每次母亲带给他的喜糖,他都会带到学校,给同学吃,到并不一定有多昂贵,也并不会好吃,但是分享中建立的感情却难能可贵。

前些日子在路上碰到他,看到他和一个保安室门口的大叔聊天。后来,保安室门口的大叔说:这样一个有素质的男孩,根本不用担心生计,走到哪里,都有人愿意帮助他。

这个男孩子并没有传统定义上的优秀,不一定能够成为职场精英,也可能取得不了所谓的成绩。但是因为他的为人,也就是教养,使他过得并没有那么孤单。

一个人的能力决定了一个人飞得高不高,一个人的教养决定了一个人飞得远不远。

有教养的孩子,才最美丽。

3、请把教养带给你的孩子

1、见人微笑问好,微笑是最美好的表情,每一个孩子都应该学会微笑,大大方方的打一声招呼,给别人留下美好的印象,爸爸妈妈一定要教给孩子。

2、大度懂分享,孩子有了好吃的好玩的,要教导他跟爸爸妈妈一起分享,也要和好朋友一起分享。

3、信守承诺,“那本书我借你”“下次一起吃饭”,这些脱口而出的话都是小小的约定,信守则会给对方留下真诚、守信的好印象。

4、不再背后说人坏话,不负责任地议论是非。即使让你觉得难以理解的地方,也要尊重别人的不同。

5、不随便动他人物品。别人东西随便用,还要带回家,这样的孩子真的让大人很尴尬。我们要告诉孩子:要拿别人东西之前,一定要获得对方的同意。

6、别人的东西,不要轻易做负面评价。比如去人家里说“你家好小啊”,人家新买的衣服“这颜色好难看啊”(人家自己觉得好就行了)。

7、当遇见别人会发生窘迫时,用自然的方式帮忙化解。当别人遭遇尴尬,比如说话说不下去的时候,不妨帮他说几句,或者给他一个台阶,避免他的尴尬,别人自然会感激你。

8、他人讲话,要认真聆听,别打断。我们不只要放下手上的事情,眼看对方,耳听对方,还要懂得适时回应,不武断评价。保持好奇与尊重,客观判断,深入倾听。

9、懂得说“谢谢”。例如迟到别人给的号吃的点心,不止一句“谢谢”,还要记得传达“这个味道很好”这样的具体感受,会让对方感到你的感谢不是一句客套。

10、有礼貌应该是对所以人,无论是上司、长辈、餐饮服务员或是路边捡垃圾的老者。

11、在电影院等需要安静的公共场合,不要大吵大闹。

12、吃饭时不发出声,不随意转盘,不翻菜,不要夹光自己喜欢的菜,有公筷使用公筷。公共场合不吃气味大,碎屑多的东西。

13、吃完东西自己收拾餐具,无论是在家,还是在KFC、M记,餐馆就餐时也尽量将食物残渣收拾碟子里,便于服务员收拾。

14、留意坐姿,不交抱双臂或跷二郎腿,小孩子在公共场所也应该有一个文明美观的坐姿。

穷养、富养,不如教养!

其实,一次礼貌的让座,一句贴心的问候,一身整洁的衣服,一手端正的笔迹,都是孩子教养好的表现。一个好的家庭门风必然养出有气质、有教养的孩子。

对于父母而言,当你每天讨论穷养、富养的时候,其实都不如教养来得实在。人之所以为贵,以其有信有礼;国之所以能强,亦云惟佳信与义。

人有教养行走八方,无教养寸步难行。

217月/170

正确的鼓励孩子做事情

发布在 邵珠庆

宝宝积极劳动,或者做出你认为“好”的某件事时,当然应该受到鼓励。但是鼓励和鼓励不同,从长远看,结果也非常不同。不恰当的鼓励,很可能导致你的孩子越来越不爱做家务、越来越不爱学习。

鼓励孩子主动做事,更应激发内在动机

我们想要让孩子主动做事情,那么最重要的就是搞清楚孩子做这件事情的动机。外在动机通常是因为可以从别人那里得到奖励,所以才去做这件事;而内在动机则是因为完成这件事情之后会有发自内心的喜悦与满足感。

每年,约有 1300 人进入西点军校,但只有约 1000 人能毕业。研究发现,具有强烈内在动机的人,毕业的可能性比平均水平高 20%。所以我们在鼓励孩子主动做事的时候,就需要注意方式方法。在保护内在动机的同时,也要避免物质奖励的负面影响。

避免对孩子“懒惰的表扬”

儿童心理学家吉姆·泰勒(Jim Taylot)曾建议父母不要对孩子使用一些通用的赞美,比如“做得好!”“真棒!”等。他把一些诸如“不错!”“很好”等表扬归类为“懒惰的表扬”,这些表扬对孩子而言几乎没有什么价值。

如果表扬孩子很聪明

这样只会强化孩子紧闭性的思维模式。孩子会认为自己的成就都是因为自己聪明,所以成功也是理所应当的,而如果遇到失败则是自己不够聪明的原因。

如果表扬孩子的努力和付出

可以提高孩子的开放性思维模式。同样在考了个好成绩之后,家长跟孩子说:“之前复习的时候你一直非常努力,所以这次考得这么好,非常棒!”这是强调孩子是因为努力才考得好。

表扬的最好方式就是描述事实

描述事实,肯定这个事情的重要性,最后表达自己对孩子完成这件事情的感受。比如“你今天主动帮妈妈晾衣服了(描述),做得很棒(肯定),妈妈非常高兴你帮妈妈做家务(表达感受)”,或者“今天早早地就把作业写完了(描述),一定非常努力(肯定),我非常为你感到高兴(表达感受)”。通过这样的表扬,孩子会慢慢建立做事情或者学习的内在动机,从而养成主动完成任务的好习惯。

从什么时候需要开始培养孩子做事的内在动机

孩子2岁就开始能感知他人的情绪状态,比如开心或不开心,而这个时候孩子会开始非常想要帮助他人,比如帮忙递东西等,这些就是亲社会行为的初端。这个时候家长就需要鼓励孩子做一些他们力所能及的事情。这个阶段孩子的内在动机非常充足,他们单单通过帮助他人就能得到极大的快乐与满足,这是一个绝佳的巩固孩子这种良好行为习惯的机会,心理学上称之为“正向加强(Positive Reinforcement )”,也就是我们通常说的奖励机制,但是这种奖励是孩子自己奖励自己(内在动机),而不是家长奖励孩子(外在动机)。

这些说起来容易,实施起来其实千难万难,中间的过程,根据孩子的不同,可能会出现各式各样的情况。在从“外在动机”转化为“内在动机”的过程中,家长需要付出的心血,一点也能不少,亦绝不应忽略。但是在自己的努力下,看着孩子一天天发生改变,变得更加优秀,更加卓越,回望背后的辛苦,我明白,这些欣慰都是教育者及家长为之努力的原因。

207月/170

javascript中的五种基本数据类型

发布在 邵珠庆

[0]5种数据类型:

[0.1]基本数据类型:Undefined、Null、Boolean、Number、String

[0.1.1]基本类型值是指简单的数据段,5种基本类型是按值访问的,因为可以操作保存在变量中的实际值

[0.1.2]基本类型的值在内存中占据固定大小的空间,被保存在栈内存中。从一个变量向另一个变量复制基本类型的值,会创建这个值的一个副本。

[0.1.3]不能给基本类型的值添加属性

[0.2]引用数据类型:Object

[0.2.1]引用类型值是指那些可以由多个值构成的对象。js不允许直接访问内存中的位置,也就是不能直接访问操作对象的内存空间。在操作对象时,实际上是在操作对象的引用而不是实际的对象。

[0.2.2]引用类型的值是对象,保存在堆内存中,包含引用类型值的变量实际上包含的并不是对象本身,而是一个指向该对象的指针。从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量最终都指向同一个对象。

[0.2.3]对于引用类型的值,可以为其添加属性和方法,也可以改变和删除其属性和方法

[1]Undefined

[1.1]Undefined类型只有一个值,就是undefined

[1.2]var a <=> var a = undefined;

[1.3]对于尚未声明过的变量,只能执行一项操作,就是使用typeof操作符检测其数据类型【但在严格模式下会导致错误】

[1.4]出现场景:

[1.4.1]已声明未赋值的变量

[1.4.2]获取对象不存在的属性

[1.4.3]无返回值的函数的执行结果

[1.4.4]函数的参数没有传入

[1.4.5]void(expression)

[1.5]类型转换

Boolean(undefined):false

Number(undefined):NaN

String(undefined):'undefined'

[2]Null

[2.1]Null类型只有一个值,就是null,逻辑角度看,null值表示一个空对象指针

[2.2]如果定义的变量将用于保存对象,最好将该变量初始化为null

[2.3]实际上undefined值是派生自null值的,所以undefined == null

[2.4]出现场景:对象不存在时

[2.5]类型转换

Boolean(null):false

Number(null):0

String(null):'null'

[注意1]null是空对象指针,而[]是空数组,{}是空对象,三者不相同

[注意2]null不能添加自定义属性

[3]Boolean

[3.1]Boolean类型只有两个值:true 和 false

[3.2]出现场景:

[3.2.1]条件语句导致系统执行的隐士类型转换

[3.2.2]字面量或变量定义

[3.3]类型转换

Number(true): 1 || Number(false) : 0

String(true):'true' || String(false):'false'

[3.4]Boolean()

Boolean(undefined):false

Boolean(null):false

Boolean(非空对象包括空数组[]和空对象{}):true

Boolean(非0): true || Boolean(0和NaN):false

Boolean(非空包括空格字符串):true || Boolean(''):false

[注意]true不一定等于1,false也不一定等于0

 [4]Number

[4.1]Number类型使用IEEE754格式来表示整数和浮点数值

[注意]可以用一个值-0来将其转换成一个数字

[4.2]三种字面量格式是十进制、八进制、十六进制

[4.2.1]八进制字面值的第一位必须是0,然后是八进制数字序列(0-7),如果字面值中的数值超出了范围,那么前导0将被忽略,后面的数值被当作十进制数解析

[4.2.2]八进制字面量在严格模式下是无效的,会导致js抛出错误

[4.2.3]十六进制字面值的前两位必须是0x,后跟十六进制数字序列,字母可大写可小写

[4.2.4]十六进制中字面值中的数值走出范围,如出现g,h等会报错

[4.2.5]在进行算术计算时,所有以八进制和十六进制表示的数值最终都将被转换成十进制数值

[4.3]数值表示:

[4.3.1]js中可以保存正0和负0,且被认为相等

[4.3.2]浮点数值:该数值中必须包含一个小数点,并且小数点后面必须至少有一位数字。

[4.3.2.1]由于浮点型数值需要的内存空间是保存整数值的两倍,因此js会不失时机地将浮点数值转换成整数值,若小数点后没有跟任何数字或者浮点值本身表示的就是一个整数,这个数值会作为整数值来保存。

[4.3.2.2]浮点数值的最高精度是17位小数

[4.3.2.3]对于极大或者极小的数,可以用科学计数法e来表示的浮点数值来表示

[4.3.2.4]默认情况下,js会将小数点后面带有6个0以上的浮点数值转换为以e表示法表示的数值

[4.3.2.5]基于IEEE754数值的浮点计算的通病是舍入误差的问题。如:0.1+0.2 === 0.3(15个0)4

[4.3.3]js中的数值范围是Number.MIN_VALUE(5e-324) —— Number.MAX_VALUE(1.7976931348623157e+308)

[4.3.3.1]如果超出正数范围,输出Infinity(正无穷大),超出负数范围,输出-Infinity(负无穷大)

[4.3.3.2]+-Infinity不能参与数值计算

[4.3.3.3]Number.MAX_VALUE+1 != Infinity,因为计算机最多保存52位尾数位,保存不了1000多位,早就失去精度,即小数位全为0,所以相加不变

[4.3.3.4]Number.MIN_VALUE - 1 != -Infinity,也是同样的原因,所以结果为-1

[4.3.3.5]可以用isFinite()来确定一个数值是不是有穷的,包含着隐式类型转换Number()

[4.3.3.6]isFinite(NaN) //false

[4.3.4]NaN

[4.3.4.1]NaN与任何值都不相等,包括NaN本身

[4.3.4.2]任何涉及NaN的操作都会返回NaN

[4.3.4.3]isNaN()来判断这个数字是不是NaN,包含着隐式类型转换Number()

[4.4]数值转换:Number()可用于任何类型,parseInt()和parseFloat专门用于把字符串转换成数值

[注意1]Number()、parseInt()、parseFloat()可以接受各种进制的数字,但对于含数字的字符串并不适用

[注意2]Number()、parseInt()、parseFloat()中数字为1.2. 会报错,但字符串为'1.2.'则不会报错

[4.4.1]Number()

Number(true):1 || Number(false):0

Number(各种进制的数字):运算后的十进制的数字,如1.0或1.或01会以1输出

Number(undefined):NaN

Number(null):0

Number(字符串):

Number(只包含数字的十进制和十六进制的字符串):运算后的十进制的数字

[注意]字符串中不识别八进制,按照十进制数字处理

Number(''和' '):0

Number(其他情况的字符串):NaN

Number(对象):

Number([]和[0]和[-0]):0

Number([数字]):运算后的数字

Number([1,2]和{}和其他对象):NaN

[4.4.2]parseInt():在转换字符串时,会忽略字符串前面的空格,直到找到第一个非空格字符。如果第一个字符不是数字字符或者负号,parseInt()就会返回NaN。如果是,则继续解析,直到解析完成或者遇到非数字字符。

[4.4.2.1]parseInt()可以识别出各种进制的整数,但在解析八进制字面量的字符串,ECMAScript3会解析八进制,但ECMAScript5没有解析八进制的能力

[4.4.2.2]parseInt()函数提供第二个参数,表示多少进制,如:parseInt('123',16或10或2)

[4.4.2.3]parseInt(各种进制的数字):运算后的十进制的数字,如1.0或1.或01会以1输出

[4.4.2.4]因为parseInt()是专门用来处理字符串转换数字的,所以parseInt(其他类型包括'')//NaN

[4.4.3]parseFloat():类似于parseInt(),会忽略字符串前面的空格,直到找到第一个非空格字符

[4.4.3.1]parseFloat()只能解析十进制字符串

[4.4.3.2]parseFloat(各种进制的数字):运算后的十进制的数字,如1.0或1.或01会以1输出

 [5]String:由单引号或双引号括起来的字符序列,任何字符串的长度都可以通过访问length属性获得

[5.1]字符字面量,也叫转义序列

\n 换行

\t 制表

\b 空格

\r 回车

\f 进纸

\\ 斜杠

\' 单引号

\" 双引号

\xnn 以十六进制nn表示一个字符(n为0-f),如\x41表示'A'

\unnnn 以十六进制nnnn表示一个Unicode字符(n为0-f),如\u03a3表示希腊字符ε

[5.2]ECMAScript中的字符串是不可变的

[5.3]字符串连接需要先创建一个新字符串,然后在新字符串中填充两个需要拼接的字符串,最后再销毁原来的字符串。这个过程在后台发生,也是在某些旧版本浏览器(IE6)拼接字符串速度慢的原因,但后来已经解决了这个低效率问题

[5.4]字符串转换

[5.4.1]toString()

Null和Undefined没有该方法

Boolean、Object、String有该方法

Number使用该方法可以传递基数2、8、10、16,如var num = 10;num.toString(2);//1010

但10.toString(2)会报错,因为数字后面不能跟标识符

[5.4.2]String()

有toString()方法,使用toString()方法

String(null);//'null'

String(undefined);//'undefined'

[5.4.3]要把某个值转换为字符串,可以使用加号操作符把它与一个空字符串''加在一起

[5.4.4]如果数组中的某一项的值是null或者undefined,那么该值在join()、toLocaleString()、toString()和valueOf()方法返回的结果中以空字符串表示

最后给大家一个简单的例子说明下这五种基本类型的不同

var testString = "Hello"; 
var testBoobean = true; 
var testUndefined = undefined; 
var testUndefined1; 
var testNull = null; 
var testObject = {a:1}; 
var testFunction = function(){return;}; 
 
alert(testString);//"string" 
alert(testBoobean);//"boolean" 
alert(testUndefined);//"undefined" 
alert(testUndefined1);//"undefined" 
alert(testUndefined2);//"undefined" 
alert(testNull);//"object" 
alert(testObject);//"object" 
alert(testFunction);//"function"
107月/170

WebSocket全双工通信入门教程

发布在 邵珠庆

 1. 什么是WebSocket
           WebSocket protocol 是HTML5一种新的协议。它实现了浏览器与服务器全双工通信(full-duplex)。一开始的握手需要借助HTTP请求完成。
                1. 传统的web通信方式
                        1. 工作模式:客户端请求-服务端响应
                        2. 适用场景:信息变化不是特别频繁的场合,如网页刷新
                        3. 不适用场景:在线游戏,实时监控
                        4. 问题
                          占用网络传输带宽:每次请求和应答都带有完整的Http头,这就增加了每次传输的数据量。
                          实时性差:在全双工通信时常采用轮询进行。

                2. 改进版web通信方式
                        1. 轮询
                          
                                1. 基于polling(轮询)技术:以频繁请求方式来保持客户端和服务端的同步
                                2. 问题:客户端的频繁的请求,服务端的数据无变化,造成通信低效
                        2. 长轮询
                          
                                1. 当服务端没有数据更新的时候,连接会保持一段时间周期直到数据或者状态改变或者过期,以此减少无效的客户端和服务端的交互
                                2. 当服务端数据变更频繁的话,这种机制和定时轮询毫无区别
                        3. 流技术
                          
                                1. 在客户端页面通过一个隐藏的窗口向服务端发出一个长连接请求。服务端接到这个请求后作出回应并不断更新链接状态以保证客户端和服务端的连接不过期。
                                2. 浏览器设计兼容和并发处理问题。
                        4. websocket
                                1. 概念:是html5开始提供的一种在单个TCP连接上进行全双工通讯协议。Websocket通信协议与2011年倍IETF定为标准RFC 6455,Websocket API被W3C定为标准。
                                2. 原理和TCP一样,只需做一个握手动作,就可以形成一条快速通道。
                                           
                                        1. 客户端发起http请求,附加头信息为:“Upgrade Websocket”
                                            
                                            
                                        2. 服务端解析,并返回握手信息,从而建立连接
                                            
                                        3. 传输数据(双向)
                                           
                                        4. 断开连接
                                3. 数据传输过程
                                        1. 以帧形式进行传输
                                                1. 大数据分片
                                                2. 支持边生成数据,把你传递消息
                                        2. 说明
                                                1. 客户端到服务端的数据帧必须进行掩码处理,服务端拖接收到未经掩码处理的数据帧,须主动关闭连接
                                                2. 服务端到客户端的数据一定不能加掩码,客户端接收到经过掩码的实际帧,须主动关闭连接
                                                3. 发现错误的一方可以发送close帧,关闭连接。
                                4. 优势
                                        1. 数据传输量大
                                        2. 稳定性高
                                5. 支持浏览器
                                        1. Firefox 4、Chrome 4、Opera 10.70以及Safari 5等浏览器的支持

       2. websocket案例说明
                1. 客户端
                        1. 创建Websocket实例
                          ws = new WebSocket("ws://127.0.0.1:10000/Server_Test.php");
1. 服务器IP:ws://127.0.0.1
2. 服务器端口:10000
3. 服务程序:Server_Test.php
2. 建立连接后回调函数
ws.onopen = function(event){}
3. 收到服务端消息后回调函数
ws.onmessage = function(event){}
4. 关闭连接后回调函数
ws.onclose = function(event){}
5. 连接错误后回调函数
                          ws.onerror = function(event)
6. 发送数据
                          ws.send('服务器,您好');
7. 查看当前连接状态
                          alert(ws.readyState)

    2. 服务端
1. 创建服务端WebSocket对象,等待客户端接入
                          $master  = WebSocket("localhost",10000);

                          首先创建Websocket,然后服务端监听相应端口,等待客户端接入
                          function WebSocket($address,$port){
                            $master=socket_create(AF_INET, SOCK_STREAM, SOL_TCP)     or die("socket_create() failed");
                          socket_set_option($master, SOL_SOCKET, SO_REUSEADDR, 1)  or die("socket_option() failed");
                           socket_bind($master, $address, $port)                    or die("socket_bind() failed");
                           socket_listen($master,20)                                or die("socket_listen() failed");
                          echo "Server Started : ".date('Y-m-d H:i:s')."\n";
                             echo "Master socket  : ".$master."\n";
                           echo "Listening on   : ".$address." port ".$port."\n\n";
                            return $master;
                           }
2. 从WebSocket中读取数据
                          $buffer = socket_read($socket,2048);
3. 当收到客户端首次连接请求后,生成握手信息并回复
                          $return_str = dohandshake($buffer);
                          socket_write($socket,$return_str,strlen($return_str));
4. 连接后,即可接收并解析出客户端的数据
                          $buffer = socket_read($socket,2048);
                          $data_str = decode($buffer);
5. 接收到用户数据后,直接回复客户端
                          socket_write($socket,$return_str,strlen($return_str));
6. 断开连接
                          socket_close($socket);
                        7. 以上6步完成全双工通信
                3. 本案例说明

                        1. 目前只可传文本,byte传输还需进一步研究

        3. 案例运行流程
            首先需要安装PHP study,然后将服务端代码放到PHP study可执行目录下,最后使用浏览器打开客户端代码去访问服务器即可进行通信。

                1. 安装PHP study,然后将PHP文件放到 D:\phpStudy\WWW 
                    
                2. 设置PHP study端口:
                    
                3. 在客户端程序中通过url去访问服务器:
                    

        4. 调试说明

                1. 客户端代码
                        1. html代码使用Hbuilder编辑完成
                        2. 打印信息使用
                          console.log("已经与服务器建立了连接rn当前连接状态:" + this.readyState);
3. 打印信息可以实时输出到控制台
2. 服务端代码
1. 服务端代码编辑同样在Hbuilder中完成
2. 服务端代码调试工具推荐使用Xdebug,我们目前使用的是打印错误日志方式进行调试
                          error_log("客户端发送数据:  $data_str \r\n", 3, "D:/phpStudy/WWW/error.log");
                        3. 注意,D:/phpStudy/WWW/error.log为日志输出路径

        5. 参考资料

                1. 认识Websocket:http://www.itpub.net/thread-1373652-1-1.html###
                2. 认识Websocket (较全面):https://my.oschina.net/u/1266171/blog/357488
                3. websocket讲解:http://wenku.baidu.com/link?url=q-RIde8I-ScuPv6wO1APa8lfX47B-6meTdm7LTNyCcSsSxOqnqzt7WtKEXzwl6YpAVG5KzMcAMRTusknr_6T9w5RC7qbZGa0elRy6b4sTZi
                4. Websocket在线测试工具:http://www.blue-zero.com/WebSocket/
                5. 客户端很简单,关键是服务端代码:http://www.yxsss.com/sg.php?fp=0&tag=websocket
                6. 使用php创建WebSocket服务:http://www.oschina.net/code/snippet_1029305_22256
                7. PHP服务器:http://www.oschina.net/code/snippet_230665_21329
                8. 在线聊天室程序:http://www.yxsss.com/ui/sk.html
                9. 在线聊天室程序详解:http://www.bitscn.com/pdb/php/201609/732585.html
                                                     http://www.111cn.net/phper/php-cy/120076.htm
10. 服务端代码详解:http://zhidao.baidu.com/link?url=cbPCqd2rdNUMqHNKhQKEqF2j5carf01upT6PHGpFFPVLZv7ef5q5avksGyNd5P06nvIltLgHCPN68YZ6Emp2ytT4NVyi1-7CUkghun4zT1i
11. java实现Websocket:http://blog.csdn.net/u011677147/article/details/47038259

107月/170

Web领域的实时推送技术

发布在 邵珠庆

作者:潘良虎
链接:https://www.zhihu.com/question/20215561/answer/26419995
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Web领域的实时推送技术,也被称作Realtime技术。这种技术要达到的目的是让用户不需要刷新浏览器就可以获得实时更新。它有着广泛的应用场景,比如在线聊天室、在线客服系统、评论系统、WebIM等。

WebSocket简介

谈到Web实时推送,就不得不说WebSocket。在WebSocket出现之前,很多网站为了实现实时推送技术,通常采用的方案是轮询(Polling)和Comet技术,Comet又可细分为两种实现方式,一种是长轮询机制,一种称为流技术,这两种方式实际上是对轮询技术的改进,这些方案带来很明显的缺点,需要由浏览器对服务器发出HTTP request,大量消耗服务器带宽和资源。面对这种状况,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽并实现真正意义上的实时推送。
WebSocket协议本质上是一个基于TCP的协议,它由通信协议和编程API组成,WebSocket能够在浏览器和服务器之间建立双向连接,以基于事件的方式,赋予浏览器实时通信能力。既然是双向通信,就意味着服务器端和客户端可以同时发送并响应请求,而不再像HTTP的请求和响应。
为了建立一个WebSocket连接,客户端浏览器首先要向服务器发起一个HTTP请求,这个请求和通常的HTTP请求不同,包含了一些附加头信息,其中附加头信息”Upgrade: WebSocket”表明这是一个申请协议升级的HTTP请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务器端的WebSocket连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。
一个典型WebSocket客户端请求头:


前面讲到WebSocket是HTML5中新增的一种通信协议,这意味着一部分老版本浏览器(主要是IE10以下版本)并不具备这个功能, 通过百度统计的公开数据显示,IE8目前仍以33%的市场份额占据榜首,好在chrome浏览器市场份额逐年上升,现在以超过26%的市场份额位居第二,同时微软前不久宣布停止对IE6的技术支持并提示用户更新到新版本浏览器,这个曾经让无数前端工程师为之头疼的浏览器有望退出历史舞台,再加上几乎所有的智能手机浏览器都支持HTML5,所以使得WebSocket的实战意义大增,但是无论如何,我们实际的项目中,仍然要考虑低版本浏览器的兼容方案:在支持WebSocket的浏览器中采用新技术,而在不支持WebSocket的浏览器里启用Comet来接收发送消息。
WebSocket实战本文将以多人在线聊天应用作为实例场景,我们先来确定这个聊天应用的基本需求。
需求分析1、兼容不支持WebSocket的低版本浏览器。
2、允许客户端有相同的用户名。
3、进入聊天室后可以看到当前在线的用户和在线人数。
4、用户上线或退出,所有在线的客户端应该实时更新。
5、用户发送消息,所有客户端实时收取。

在实际的开发过程中,为了使用WebSocket接口构建Web应用,我们首先需要构建一个实现了 WebSocket规范的服务端,服务端的实现不受平台和开发语言的限制,只需要遵从WebSocket规范即可,目前已经出现了一些比较成熟的WebSocket服务端实现,比如本文使用的Node.js+Socket.IO。为什么选用这个方案呢?先来简单介绍下他们两。
Node.jsNode.js采用C++语言编写而成,它不是Javascript应用,而是一个Javascript的运行环境,据Node.js创始人Ryan Dahl回忆,他最初希望采用Ruby来写Node.js,但是后来发现Ruby虚拟机的性能不能满足他的要求,后来他尝试采用V8引擎,所以选择了C++语言。
Node.js支持的系统包括*nux、Windows,这意味着程序员可以编写系统级或者服务器端的Javascript代码,交给Node.js来解释执行。Node.js的Web开发框架Express,可以帮助程序员快速建立web站点,从2009年诞生至今,Node.js的成长的速度有目共睹,其发展前景获得了技术社区的充分肯定。
Socket.IOSocket.IO是一个开源的WebSocket库,它通过Node.js实现WebSocket服务端,同时也提供客户端JS库。Socket.IO支持以事件为基础的实时双向通讯,它可以工作在任何平台、浏览器或移动设备。
Socket.IO支持4种协议:WebSocket、htmlfile、xhr-polling、jsonp-polling,它会自动根据浏览器选择适合的通讯方式,从而让开发者可以聚焦到功能的实现而不是平台的兼容性,同时Socket.IO具有不错的稳定性和性能。
编码实现

本文一开始的的插图就是效果演示图:可以点击这里查看在线演示,整个开发过程非常简单,下面简单记录了开发步骤:
安装Node.js根据自己的操作系统,去Node.js官网下载安装即可。如果成功安装。在命令行输入node -v和npm -v应该能看到相应的版本号。


搭建WebSocket服务端

这个环节我们尽可能的考虑真实生产环境,把WebSocket后端服务搭建成一个线上可以用域名访问的服务,如果你是在本地开发环境,可以换成本地ip地址,或者使用一个虚拟域名指向本地ip。
先进入到你的工作目录,比如 /workspace/wwwroot/plhwin/realtime.plhwin.com,新建一个名为package.json的文件,内容如下:


接下来使用npm命令安装express和socket.io


安装成功后,应该可以看到工作目录下生成了一个名为node_modules的文件夹,里面分别是express和socket.io,接下来可以开始编写服务端的代码了,新建一个文件:index.js


命令行运行node index.js,如果一切顺利,你应该会看到返回的listening on *:3000字样,这说明服务已经成功搭建了。此时浏览器中打开 localhost:3000 应该可以看到正常的欢迎页面。
如果你想要让服务运行在线上服务器,并且可以通过域名访问的话,可以使用Nginx做代理,在nginx.conf中添加如下配置,然后将域名(比如:realtime.plhwin.com)解析到服务器IP即可。


完成以上步骤,realtime.plhwin.com:3000的后端服务就正常搭建了。


服务端代码实现前面讲到的index.js运行在服务端,之前的代码只是一个简单的WebServer欢迎内容,让我们把WebSocket服务端完整的实现代码加入进去,整个服务端就可以处理客户端的请求了。完整的index.js代码如下:


客户端代码实现进入客户端工作目录/workspace/wwwroot/plhwin/demo.plhwin.com/chat,新建一个index.html:

上面的html内容本身没有什么好说的,我们主要看看里面的4个文件请求:
1、realtime.plhwin.com:3000
2、style.css
3、json3.min.js
4、client.js
第1个JS是Socket.IO提供的客户端JS文件,在前面安装服务端的步骤中,当npm安装完socket.io并搭建起WebServer后,这个JS文件就可以正常访问了。

第2个style.css文件没什么好说的,就是样式文件而已。

第3个JS只在IE8以下版本的IE浏览器中加载,目的是让这些低版本的IE浏览器也能处理json,这是一个开源的JS,详见:JSON 3

第4个client.js是完整的客户端的业务逻辑实现代码,它的内容如下:


至此所有的编码开发工作全部完成了,在浏览器中打开 demo.plhwin.com/chat/ 就可以看到效果了。

上面所有的客户端和服务端的代码可以从Github上获得,地址:github.com/plhwin/nodej

下载本地后有两个文件夹 client 和 server,client文件夹是客户端源码,可以放在Nginx/Apache的WebServer中,也可以放在Node.js的WebServer中。后面的server文件夹里的代码是websocket服务端代码,放在Node.js环境中,使用npm安装完 express 和 socket.io 后,node index.js 启动后端服务就可以了。
留给我们的思考

1、假设是一个在线客服系统,里面有许多的公司使用你的服务,每个公司自己的用户可以通过一个专属URL地址进入该公司的聊天室,聊天是一对一的,每个公司可以新建多个客服人员,每个客服人员可以同时和客户端的多个用户聊天。
2、又假设是一个在线WebIM系统,实现类似微信,qq的功能,客户端可以看到好友在线状态,在线列表,添加好友,删除好友,新建群组等,消息的发送除了支持基本的文字外,还能支持表情、图片和文件。
有兴趣的同学可以继续深入研究。
--------------------------
上面是我前段时间写的一篇与WebSocket这个主题相关的文档,就直接贴过来了,原文请见:使用Node.js+Socket.IO搭建WebSocket实时应用

57月/170

关于对称加密算法与非对称加密算法

发布在 邵珠庆

我们来讲解下关于各种加解密算法的比较,其中有对称加密算法,非对称加密算法,散列算法等等。

称加密算

对称加密算法用来对敏感数据等信息进行加密,常用的算法包括:

DES(Data Encryption Standard):数据加密标准,速度较快,适用于加密大量数据的场合。

3DES(Triple DES):是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高。

AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高;

AES与3DES的比较

算法名称 算法类型 密钥长度 速度 解密时间(建设机器每秒尝试255个密钥) 资源消耗
AES 对称block密码 128、192、256位 1490000亿年
3DES 对称feistel密码 112位或168位 46亿年

非对称算法

RSA:由 RSA 公司发明,是一个支持变长密钥的公共密钥算法,需要加密的文件块的长度也是可变的;

DSA(Digital Signature Algorithm):数字签名算法,是一种标准的 DSS(数字签名标准);

ECC(Elliptic Curves Cryptography):椭圆曲线密码编码学。

ECC和RSA相比,在许多方面都有对绝对的优势,主要体现在以下方面:

抗攻击性强。相同的密钥长度,其抗攻击性要强很多倍。

计算量小,处理速度快。ECC总的速度比RSA、DSA要快得多。

存储空间占用小。ECC的密钥尺寸和系统参数与RSA、DSA相比要小得多,意味着它所占的存贮空间要小得多。这对于加密算法在IC卡上的应用具有特别重要的意义。

带宽要求低。当对长消息进行加解密时,三类密码系统有相同的带宽要求,但应用于短消息时ECC带宽要求却低得多。带宽要求低使ECC在无线网络领域具有广泛的应用前景。

下面两张表示是RSA和ECC的安全性和速度的比较。

攻破时间(MIPS年) RSA/DSA(密钥长度) ECC密钥长度 RSA/ECC密钥长度比
104 512 106 5:1
108 768 132 6:1
1011 1024 160 7:1
1020 2048 210 10:1
1078 21000 600 35:1
攻破时间(MIPS年) RSA/DSA(密钥长度) ECC密钥长度 RSA/ECC密钥长度比
104 512 106 5:1
108 768 132 6:1
1011 1024 160 7:1
1020 2048 210 10:1
1078 21000 600 35:1

RSA和ECC安全模长得比较

功能 Security Builder 1.2 BSAFE 3.0
163位ECC(ms) 1,023位RSA(ms)
密钥对生成 3.8 4,708.3
签名 2.1(ECNRA) 228.4
3.0(ECDSA)
认证 9.9(ECNRA) 12.7
10.7(ECDSA)
Diffie—Hellman密钥交换 7.3 1,654.0

RSA和ECC速度比较

散列算法

散列是信息的提炼,通常其长度要比信息小得多,且为一个固定长度。加密性强的散列一定是不可逆的,这就意味着通过散列结果,无法推出任何部分的原始信息。任何输入信息的变化,哪怕仅一位,都将导致散列结果的明显变化,这称之为雪崩效应。散列还应该是防冲突的,即找不出具有相同散列结果的两条信息。具有这些特性的散列结果就可以用于验证信息是否被修改。

单向散列函数一般用于产生消息摘要,密钥加密等,常见的有:

l         MD5(Message Digest Algorithm 5):是RSA数据安全公司开发的一种单向散列算法,非可逆,相同的明文产生相同的密文。

l         SHA(Secure Hash Algorithm):可以对任意长度的数据运算生成一个160位的数值;

SHA-1MD5的比较

因为二者均由MD4导出,SHA-1和MD5彼此很相似。相应的,他们的强度和其他特性也是相似,但还有以下几点不同:

l         对强行供给的安全性:最显著和最重要的区别是SHA-1摘要比MD5摘要长32 位。使用强行技术,产生任何一个报文使其摘要等于给定报摘要的难度对MD5是2128数量级的操作,而对SHA-1则是2160数量级的操作。这样,SHA-1对强行攻击有更大的强度。

l         对密码分析的安全性:由于MD5的设计,易受密码分析的攻击,SHA-1显得不易受这样的攻击。

l         速度:在相同的硬件上,SHA-1的运行速度比MD5慢。

对称与非对称算法比较

以上综述了两种加密方法的原理,总体来说主要有下面几个方面的不同:

l         在管理方面:公钥密码算法只需要较少的资源就可以实现目的,在密钥的分配上,两者之间相差一个指数级别(一个是n一个是n2)。所以私钥密码算法不适应广域网的使用,而且更重要的一点是它不支持数字签名。

l         在安全方面:由于公钥密码算法基于未解决的数学难题,在破解上几乎不可能。对于私钥密码算法,到了AES虽说从理论来说是不可能破解的,但从计算机的发展角度来看。公钥更具有优越性。

l         从速度上来看:AES的软件实现速度已经达到了每秒数兆或数十兆比特。是公钥的100倍,如果用硬件来实现的话这个比值将扩大到1000倍。

  1. 三.加密算法的选择

由于非对称加密算法的运行速度比对称加密算法的速度慢很多,当我们需要加密大量的数据时,建议采用对称加密算法,提高加解密速度。

对称加密算法不能实现签名,因此签名只能非对称算法。

由于对称加密算法的密钥管理是一个复杂的过程,密钥的管理直接决定着他的安全性,因此当数据量很小时,我们可以考虑采用非对称加密算法。

在实际的操作过程中,我们通常采用的方式是:采用非对称加密算法管理对称算法的密钥,然后用对称加密算法加密数据,这样我们就集成了两类加密算法的优点,既实现了加密速度快的优点,又实现了安全方便管理密钥的优点。

那采用多少位的密钥呢? RSA建议采用1024位的数字,ECC建议采用160位,AES采用128为即可。

  1. 四.密码学在现代的应用

保密通信:保密通信是密码学产生的动因。使用公私钥密码体制进行保密通信时,信息接收者只有知道对应的密钥才可以解密该信息。

数字签名:数字签名技术可以代替传统的手写签名,而且从安全的角度考虑,数字签名具有很好的防伪造功能。在政府机关、军事领域、商业领域有广泛的应用环境。

秘密共享:秘密共享技术是指将一个秘密信息利用密码技术分拆成n个称为共享因子的信息,分发给n个成员,只有k(k≤n)个合法成员的共享因子才可以恢复该秘密信息,其中任何一个或m(m≤k)个成员合作都不知道该秘密信息。利用秘密共享技术可以控制任何需要多个人共同控制的秘密信息、命令等。

认证功能:在公开的信道上进行敏感信息的传输,采用签名技术实现对消息的真实性、完整性进行验证,通过验证公钥证书实现对通信主体的身份验证。

密钥管理:密钥是保密系统中更为脆弱而重要的环节,公钥密码体制是解决密钥管理工作的有力工具;利用公钥密码体制进行密钥协商和产生,保密通信双方不需要事先共享秘密信息;利用公钥密码体制进行密钥分发、保护、密钥托管、密钥恢复等。

基于公钥密码体制可以实现以上通用功能以外,还可以设计实现以下的系统:安全电子商务系统、电子现金系统、电子选举系统、电子招投标系统、电子彩票系统等。