开发背景

6月,一个事件多发的月。
受各种政治事件影响,国际互联网的连接变得非常敏感。
大量IP被封锁,联网工具无法使用,连SSH都无法连接,查资料变得异常困难,严重影响到开发。

工作流程

为了保证兼容性,跟某知名联网工具基本一致。
本地客户端支持HTTP/Socks4/Socks5网络连接,支持Pac模式。

连接合并

与某工具最大的不一样,项目使用的是单一连接。
所有的资源请求在客户端与服务端之间,都会转变为单一连接。
简单地说,就是相当于项目内建了HTTP/2的多路复用加速功能。
在流量干扰严重的情况下,连建立连接都是困难的,浏览器的多个请求的连接建立会变得非常缓慢,甚至失敗。
通过单一连接,不需要多次新建连接,减免了连接握手的时间,可以维持一个相对稳定的网络,也增加了隐匿性。

乱序发送

在服务端与客户端的数据传输上,数据被分拆成多个数据包,乱序发送,再由客户端多线程下载、组装、还原原始数据。
一方面是方便多线程加速下载,另一方面,因为原始数据被打乱了,大量穿插其他数据,所以更难检测出原始数据,增加隐匿性。
因为流量加密,数据分拆乱序,以及TCP分界等的原因,从ISP的角度来看,即使是复制所有连接数据,也无法获得正常的原始文件/加密文件。

白名单

客户端支持白名单功能,结合Pac模式实现黑白名单。
白名单不进行流量加密,直接走本地流量,加速访问。

双向认证

服务端与客户端之间采用证书双向认证。
一方面减少网络攻击,另一方面也可以伪装成普通的SSL/TLS流量。

运行效果

在这个政治事件多发的月份,某工具连接30秒就断开,完全无法使用的情况下,通过DreamSocks可以稳定地浏览国际互联网。

开发背景

在Chrome出世之前,使用了多年的Firefox。Firefox的扩展是一个很好用的功能。
然后,Firefox越来越作死了,先是v29后部分扩展不兼容,经过了一段时间的扩展升级,好不容易解决了。
再来就是v56后,扩展要签名,又分了旧式扩展,直接把多年的扩展给失效了。
多次折腾下来,我这种从Firefox v2版用到v56版多年的死忠也表示受不了。
整个项目,都是因为Frefox的扩展问题而开发的。

关键扩展

我常用的扩展很多,但有2个实在是无法在Chrome上找到替代。
一个是远程控制扩展,也因此产生了DreamRemote项目。
另一个就是Show IP,后面升级为Show Location,再到Firefox v56后就无法使用了。
一直希望能在Chrome上找到替代,然而多年无果。

功能介绍

主要功能是分析网站信息,这对我来说非常重要。
例如获取服务器的IP地址,服务器的地理信息,机房信息等等。

动图演示

项目截图

写在前面

  1. 50K上传几个G的视频不易,请勿删除视频,请勿删除会员等信息。
  2. 重启、重载会对直播,聊天等服务产生影响 ,为了他人体验请勿随便重启、重载。
  3. 电台播放列表的节目上传和编辑、压制等是有操作要求的,你可以尝试编排节目但请不要保存或删除,以免影响面试的演示。
  4. 因多人共用账号,未读消息计数可能不准确。具体原因为,你没有读这条新消息,但其他人用相同的账号读了,所以在你的角度计数就不准确了。
  5. 因为服务器在境外,网速不佳。为了尽可能地流畅,我把视频交谈的画质调到非常低,并非是手机的摄像头的问题。
  6. 这个项目,是我对BS端的可能性,HTML5的可能性的一个探讨[类似于DreamRemote],用了连国外资料都不全的新技术,兼容性自然会比较差,会比较偏较新的浏览器版本。建议使用Chrome v70+。

兼容列表

兼容列表里的数据是理论数据,我实际上没有那么多的设备去一个个测试。如果列表内有不兼容现象,可以与我联系,请注意要提供浏览器版本和设备信息。

开发环境
PC:Chrome v75,Android: Chrome v72,iOS:iOS 10,macOS:v10.12 Safari 10.1。

视频直播
PC: Chrome v55+[2016-12发布],Android:同PC版,iOS:iOS10+,macOS:v10.12

视频点播
PC: Chrome v55+,Android:同PC版,iOS:iOS10+,macOS:v10.12 Safari 10.1

视频聊天
PC: Chrome v55+,Android:个人无足够设备测试,建议v70+,iOS:不支持,macOS:不支持

在线演示

测试账号:demouser1 至 demouser5,5个测试账号

测试密码:同账号名

后台账号:admin

后台密码:admin

前台地址(Go版):http://s.dm1.in/K

后台地址(Go版):http://s.dm1.in/L

前台地址(Node版):http://s.dm1.in/H

后台地址(Node版):http://s.dm1.in/I

动图演示

左为浏览器,右为手机。笔记本配置不足,且模拟器没有硬件加速,卡顿请见凉。

开发背景

这是我第一个可以公开展示的Node.js作品,也可能是最后一个。
在出发点和项目构思上,跟DreamRemote一样,是我个人对BS端的可能性,对HTML5的可能性的一次尝试,一个探讨。
之前所做的项目,都是偏向于后台服务功能,服务对象是后台工作人员。而在这个项目里,则更注重交互与用户体验,服务对象则是普通用户。
采用Node.js开发的原因,是因为其他的Node.js项目展示有困难,还有就是以往做的项目框架都是针对传统的Web结构的,并不完全适用与DreamVideo,即使是通过升级框架解决,也会大幅改变原有的框架结构,以后升级维护无法兼顾双方,还有就是想测试Node.js的可能性,等等。就干脆用新语言,从零开始重新做框架、做中间件,做全新开发了。

全特效项目

以往展示的项目,都是偏后台功能的。而在本项目中,比较注重前端的展示。花了不少心思调整,做成了全特效项目。
比如明显的,换页时的滑动特效,视频播放时增加的抖动效果以实现重量感,还有视频聊天时的呼吸效果等等。

项目开发

本项目实际上是由几个看起来完全不相关的项目整合而成的。
整合的原因是,这几个项目负载都很大,虽然看起来功能上不相似,但实现上有共用的地方,所以就整合在一起,减少重复的运行资源使用。
DreamVideo,主要功能是电视直播,视频点播,直播弹幕互动,点播弹幕互动。
DreamChat,主要功能是即时聊天,群组聊天,视频聊天。
DreamLxxx,暂做保留。
统一合并为DreamVideo。

直播与点播

表面上看起来都是播放视频,但技术实现上是完全不一样的。
在使用上的明显区别,是点播有进度条可以拖动观看,但是直播没有进度条。直播放的是实时的视频,而点播放的是视频文件。
直播需要处理节目延迟,以及多人同时观看同一套节目的内容分发处理,节目的实时解码编码成各种视频格式以满足各种设备的兼容,所以负载主要在CPU和内存上。
点播为了解决各设备的兼容会有转码环节(非实时,项目因服务器配置不足未实现此功能),因此一套节目会产生多种格式的视频文件,也就是说负载主要集中在磁盘上,多用户对多视频文件的大量IO请求,以及各种兼容格式视频文件的储存空间。
另外,点播因为有进度条的关系,还需要处理随机播放,不可能让用户为了看后面几分钟,而把整个文件下完,既浪费用户时间也浪费带宽。

直播节目单

在直播的设计上,是参考电视台的模式设计的。节目一套接一套,24小时不停播。为了要实现无缝连续播放的效果,所以对节目源有相当的要求。
在节目单编制上,因为是设计成24小时不停播的,所以使用了30小时跨日营业工作制。根据以往网站的监控,凌晨3-5时是访客人数最少的时间段,目前项目设定为凌晨5时(即29时)为跨日时间点,凌晨5时前的节目为当天节目,凌晨5时后的为次日节目。
跨日时间点可按需配置。

节目编制

节目编制允许对10天的节目进行预编制,到节目当天系统会自动根据节目单进行播放。
在拖动编辑节目单的时候,因节目长短不一,导致播放时间可能提前或者延后。为了能更直观准确地管理节目播放时间,实现了播放时间的实时显示。
节目单的最后会有黄色或者是红色的提示。黄色的意思是,该节目在跨日时间点里播放,所以得不到完整的播放,也就是播放到节目中途,系统就会切换到下一天的节目表。红色表示该节目超过了跨日时间点,系统已经切换到下一天的节目单了,所以得不到播放。
实际操作上为保证24小时不断播、不停播,是要求节目编制到黄色和红色的跨日点,而跨日点的节目建议仿效电视台,以公益广告代替。

节目更新

节目更新包括两部分。

  1. 观众在播放完一套节目后,节目列表的更新,具体表现为把播放结束的节目移出播放列表。
  2. 后台临时调整节目单,应用场景例如,如电视台临时对某节目进行停播,或者插播临时应急新闻、插播特别节目等等。

在1里,看起来是个很简单的前端问题,似乎把旧节目移出播放列表就完事了,但实际上不行。如果使用静态的节目表,则无法对2里的场景实时反应过来,观众会看到一个与节目单不符的节目。如果使用动态的节目单,当播放结束后刷新节目单,因为直播是多人同时观看的,特别是热门节目,这就导致同一个时间点里大量的访问请求高峰,给系统带来很大的压力。
在2里,调整当前的节目单意味着节目重排,系统要断开当前节目并播放新节目,需要保证直播在观众无感知的前提下顺利切换。不能因为临时插播新闻,就导致观众断线,需要刷新才能重新观看直播。

视频弹幕

弹幕是一种很好的交互工具,连腾讯官方也大规模采用,据说某些电视台也打算采用以增加与观众的交互,所以就在项目里增加了这个功能。
视频弹幕在项目里也分了两种,直播弹幕和点播弹幕。直播弹幕是实时显示给直播观众的,而点播的弹幕则是在视频的固定时间点里显示,两者的实现完全不同。

即时聊天

主要分好友间对聊,以及群聊。为了方便演示,就去掉了添加好友之类的环节。
这也是我对BS端、HTML5、用户体验的一次尝试,一次探讨。
以各位多年的QQ、微信使用经验,相信也不需要多做介绍了。
WebQQ在2019年1月1日正式关闭,而本项目也起于2019年,这完全是不小心撞上火车了。

群组聊天

其实这个聊天工具,也没有太多可介绍的,因为大部分跟QQ、微信差不多,基本上实际操作一遍就了解了。
可以提一个不太明显的地方吧,群组消息的限制。
用户加群之后,并不是说可以无限制地浏览群组消息。在用户加群之前的消息也是不能查看的。
可能与很多人的预期不一样,群组消息的设计是个难点。可以举例说一下未读消息吧。
如果是有客户端(PC客户端,手机客户端),可以在连网的时候直接获取到最新的群消息,然后提示一下多少条消息未读就可以了。
但是,Web端不能这样做啊。Web端里,浏览器是不会长期储存用户消息的。
解决方案想过多种,例如在发消息的时候,根据用户是否在线,对未读消息进行累加。假设一个500人的群,发一条消息要更新499人的数据,这数据库负载是有多难看。而且如果群聊活跃度高呢?有300人一直在群聊呢?那数据库压力简直不可想像。
根据用户离线时间,实时统计出新消息数量。这样的话,每次登录都去统计一次海量的群聊消息,负载也不好看,而且要是用户加了好几个群呢?得要数据库刷多少个群的海量消息?

XSS,CS防御

跟以往做后台发布不一样,在后台发布的消息必然是有官方账号认证的。而在本项目里任何人都可以发布消息。不单是在即时聊天里,如果用户在视频直播里,通过XSS发布视频弹幕,那结果是不可想像的。所以XSS的防御始终贯彻了整个项目,类似的还有CS防御。

视频聊天

相信整个项目里,最亮眼的部分应该就是这个了。
跟前面的即时聊天的设计完全不一样。即时聊天时的消息推送,是用户对用户的,而视频聊天则是端对端,或者说设备对设备的。
具体来说,就是一条文本消息,发送给好友,该好友登录的所有端都可以收到,唯一条件就是登录的账号是好友的账号,消息的推送是以用户为凭证。
而视频聊天是端对端的,即使是同一个账号,但是能进行视频聊天的,只有点击了“同意”的那个一个端。同样的,能进行“双方视频”的只有申请视频聊天的那个端。
这样的设计,一方面是为了应对多人用同一账号登录的演示问题,不能说因为别人用同一账号视频,自己就无法演示视频,或者说我在演示视频的时候,会有其他人通过同一账号收到我的视频。另一方面就是实现用户通过多设备登录,进行多人同时视频聊天的可能性。

视频录像

为了将来可能的,某些监管部门的要求,视频聊天的记录是可查的,所有视频是在服务器有实时录像,三天后自动删除。
因为隐私关系,现在演示的项目里,以及将来演示项目的更新里,都不会开放这类视频录像的观看以及下载。类似的,在项目里的真实IP都是隐藏的,不会公开。

前台演示

后台演示

后台内容较多,另开页面

面向人群

在校学生、网吧顾客

功能描述

顾客方面,按热门、最新等条件分页显示游戏运行图标,改善顾客体验;后台方面:对比更新,使用多路分流+还原穿透技术极大减轻工作量,统计热门游戏信息

极速加载

由于游戏数量比较多,达到100个以上,可以想像一下,在桌面里有100个图标,要全部显示出来也是要很久的。

再加上杀毒软件的干扰,会对访问的EXE文件逐一进行病毒扫描,还有游戏的启动程序基本达到3M以上,更加重了加载负担。

通过在服务端分离应用程序与ico文件实现了极速加载,使原来30秒才能加载完成的图标,能在1秒内完全加载。

辅助工具

右侧默认是公告内容。但如果游戏有相关的辅助工具、外挂等相关应用就会显示出来,供客户使用。例如主图标是QQ,但点到的时候右侧会自动显示珊瑚虫QQ。

自动导入注册表

主机是有还原系统的。但部分游戏需要一些注册表数据才能正常运行。

项目实现了注册表的自动导入,让游戏可以正常运行。

原来主机系统是需要安装一次游戏再封包的,自从加入此功能以来就不需要了。

没有游戏多余数据的干扰,也让母盘系统更纯净,系统启动更快。

对比更新

网络游戏更新是常有的事,当时的网络只有100M,不能完全通过无盘负载。

以有盘+无盘的方式实现更多的游戏。

有盘游戏是需要更新的,但动辄几个G的游戏更新,耗时耗力耗网络。

通过对比更新,只更新需要更新的游戏数据,加快了游戏更新速度并极大地减少了各种损耗。

穿透更新

游戏是在还原系统的保护下的,一旦重启数据就会恢复原状,更新完的游戏也需要再次更新。

穿透更新,让游戏更新数据可以穿透还原系统,更新后的文件在系统里面固化,重启后就不需要再次更新了。

多路分流

当时网络只有百兆,并不普及千兆网络。

服务器是通过一块4口百兆网卡跟局域网相连。

通过网线,让服务器跟多个网络交换机直连,这样的话,就相当于增加了4倍网速。

但是,这部分网速是不能直接利用的。

因为各交换机之间是百兆相连,交换机之间的带宽成为了瓶颈所在,甚至在跨交换机取服务器数据的时候,流量本身会影响到网络交换速度。

通过多路分流,让客户机直接跟所在交换机里,直连的服务器端口进行连接并获取数据,加速游戏更新、无盘的使用。

项目演示

因项目的运行需要服务端的配合,再加上特殊系统,专门的设备等等无法完全重现,只做基本演示。

开发背景

以前计生办都是用纸质办公,纸质登记,查找记录不方便。

为了解决这个问题,再加上当时单位企业在推广无纸化办公、电子办公,还有一些其他原因的推动下,公司收到了相关的解决方案的咨询,最终决定开发一个制证工具。

因为当时公司并不是开发公司,我在公司也不是开发岗位,公司也只是让我在业余时间里做,所以本项目虽然有公司背景,但在分类上是属于个人项目。

面向人群

乡镇计生服务站文员,计算机水平在仅会普通打字、打印(配备手写板)。

功能描述

高效率,少输入,易于使用。实时拍摄被登记人员照片,淘汰人手纸质登记,数据库设计,可按需统计每年、每月、各地登记人员信息,方便日后可开展多窗口同时登记业务。

自动操作

自动识别身份证、验证身份证正确,防止以往人手纸质登记时的错误。

自动根据登记者性别,选择手术类型,防止一些手术填写错误。

自动计算年龄,防止以往人手纸质登记时的错误。

项目演示

开发背景

继计生办制证完成后,对方比较满意,就再进一步推进电子办公。

其中有一个需要就是,希望能对工作人员的服务进行评价,以方便改进服务。

就决定继续开发,由公司提供触屏一体化电脑,帮助计生办解决问题。

面向人群

没接触过电脑的普通群众。

功能描述

用手指点两下即可完成评价。管理员密码限制以及每月报表数据导出功能,方便局上级领导检查各乡镇情况。

项目成果

获全县16个乡镇计生服务站连同触屏一体化电脑统一采购使用。

项目演示

项目统一硬件标配触屏一体机,没有鼠标键盘。

在线演示

管理员帐号:admin
管理员密码:12345678
可自行注册普通帐号
前台访问地址:http://s.dm1.in/A
后台管理地址:http://s.dm1.in/B

开发工具

Nginx 1.7.8+PHP 5.6.5+MySQL5.6.23+Scite+Dreamweaver CS6+PhotoShop CS3+ Smarty 3.1.21

功能描述

前台实现用户注册登录,浏览、搜索、推荐图书,申请借书,借书管理,个人资料管理等功能。后台实现图书上架下架,搜索分类,借书还书管理,借书统计报表。

开发时间

2015年1月24日至1月29日

项目截图

后台截图

在线演示

管理员帐号:admin
管理员密码:12345678
可自行注册普通帐号
前台访问地址:http://s.dm1.in/8
后台管理地址:http://s.dm1.in/9

开发工具

Nginx 1.7.10+PHP 5.6.6+MariaDB 10.0.16+PHPStorm 8.0.3+Dreamweaver CS6

开发框架

ThinkPHP 3.2.3

功能描述

前台主要实现用户注册登录、浏览、搜索商品,将需要商品添加购物车、收藏夹,生成订单,结算,支付、确认收货等。后台实现商品的上架下架、隐藏、库存管理等,订单发货、订单收益统计,年度、月度收益统计报表等功能。

开发时间

2015年2月25日至3月5日

项目演示

后台截图

开发背景

每天坐地铁通勤,总觉得很浪费时间。

不如找几本小说充实一下自己。

基于这种想法,开始了地铁小说阅读之旅。

首先,我的小说都是自己下载的。找过几个小说阅读器,总有那么点问题。

比较典型的,就是无法记录阅读进度,关闭重开后就从第一页重新开始。

还有就是白纸黑字,看久了始终觉得不舒服。

综合来说,Adobe Acrobat Reader这个老牌的PDF阅读器却是最好的。

但是有一个比较麻烦的问题,就是我小说里, PDF格式的太少,多数是zip/rar的压缩包,里面是小说扫描图,这种情况下要使用Adobe Acrobat Reader的话就得自己去转格式了,始终是不方便。

于是,就开始设计DreamReader项目。

夜间模式

看小说的话,如果是实体本,白纸黑字也是可以的。在以前貌似有推广过一段时间的黄纸黑字的笔记本,说是可以降低对比度保护视力。

但是,对于电子小说来说,白底黑字实在是不适合,对比度太大了,长时间阅读会导致眼睛不舒服。在晚上看的时候,再是照得自己一脸白的,就像是对着手电筒一样。

这时候使用夜间模式就比较合适了,降低屏幕发光的部分,减少眼睛负担。

特别是近年来大力推广的Amoled屏幕,黑色的像素不发光,还能节省电池。

闹钟功能

原名DreamAlarm。

可能有人觉得我在一个小说阅读器里加一个闹钟,设计是有点奇怪。

但这个整个DreamReader应用,本身就是为了方便我的日常生活而设计的。

当然我也可以单独再做一个DreamAlarm,只是觉得功能有点少,单独再开一个APP似乎有点浪费,就放一起了。

休息闹钟

其实我一直以来都对传统闹钟的功能不满。

为什么闹钟都要设定响的时间,而不是不响的时间呢?

作为一名上班族,上班才是最平常的事,尤其在一个经常加班的公司,休息才是最稀有的事。

以传统闹钟的做法,每当休息日关闹钟,麻烦不说,一旦不小心还会忘记在工作日重新打开闹钟,后果很严重。公司是大小周制度,固定周一至周五的闹钟是行不通的。

所以决定反其道而行之,在DreamAlarm里设定的都是休息时间,也就是闹钟不响的日期。

实话说,用起来还真的是出乎意料的方便。

提前设置好往下1,2个月的单休、双休日,还有一些五一、国庆之类的假期,基本上整个月都不用烦恼要不要开关闹钟。

有时候临时开会说取消假期的话就把休息日取消掉就行了,当然,我也没见过有增加假期的例会就是了。

顺便还能记录下上班的情况。

海量音乐铃声

更换闹钟的音乐铃声也是十分常见功能的,毕竟连系统都自带这种功能。

但是同一个铃声,听个十来遍还行。但对于上班族来说,听多了,真的很烦。这时候就需要更换一个铃声了。

所以,一直以来都对传统的闹钟铃声设置有所不满。

为什么都只能设置一首音乐做为闹钟铃声了?

于是,在DreamAlarm里,允许海量音乐铃声。

把几部OST打包进去,每次闹钟随机播放,3个月不重样!

不过也有坏处,就是有时候听得好听了,会多听一会。

二维码识别

原名DreamQRcode。

这可能又是一个奇怪的功能,被加到小说阅读器里。

其实是因为工作里,有时候需要对二维码扫码,分析内部数据。

如果用微信之类的扫码,会直接跳到网页上,不太方便。

所以就干脆自己做一个扫码识别。

但是为了一个二维码小功能,单独做一个APP有点夸张,就直接放到DreamReader里了。

项目截图