换到 Ghost 上 http://zhowkev.in
最近尝试了下 Ghost,高效的 Markdown 编辑器,优雅的设计,都是我想要的,所以决定迁移,欢迎访问新地址 http://zhowkev.in
he wasn't even looking at me and he found me
Xuebing Du
art blog(derogatory)
Aqua Utopia|海の底で記憶を紡ぐ
tumblr dot com

izzy's playlists!
wallacepolsom
DEAR READER
styofa doing anything

PR's Tumblrdome
KIROKAZE
Cosmic Funnies

祝日 / Permanent Vacation
Today's Document

@theartofmadeline

Alisa U Zemlji Chuda
TVSTRANGERTHINGS
seen from United States
seen from United States
seen from United States
seen from United States
seen from United States
seen from Italy

seen from T1

seen from Netherlands
seen from United States
seen from United States
seen from United States

seen from United States

seen from United States

seen from United States
seen from United States
seen from United States
seen from United States

seen from Indonesia
seen from United States

seen from United States
@kevinzhow
换到 Ghost 上 http://zhowkev.in
最近尝试了下 Ghost,高效的 Markdown 编辑器,优雅的设计,都是我想要的,所以决定迁移,欢迎访问新地址 http://zhowkev.in

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch • No registration required • HD streaming
每个人有每个人的性格和气质。但是一定要记得自己。不要在任何情况迷失。
老王 (via yibie)
赞
到底什么时候才用跨平台框架写 App
GTK 我就不提了,这个几乎没发生过美好的跨平台程序。
最近用 QML/C++ 写跨平台程序,遇到了几个很蛋疼的地方,让我想起了数年前我曾经说过再也不用跨平台框架写 App,还好我目前只付出了不到两天的时间。
为什么选择原生框架
1.原生框架往往更加强大
2.对 App 的把控能够做到像素级完美
3.完美支持平台特性
4.多媒体处理不会是个坑
为什么选择 Qt 这样的框架
1.看起来很美
2.QML 写起来确实爽
3.经过旷日持久的调试后可以支持多种平台
4.可能节省了时间
5.Linux 下写 App Qt 是个好的选择
为什么不选择跨平台框架
1.虽然 QML 有很多看上去很完美的特性,但是它存在的坑可能是毁灭性的,让你深陷解决框架不能做到的事情上而不是做你想要做的东西。
2.处于开发生态的超级小众,意味着没有足够的资料。
3.你付出的成本可能高于任何一个原生框架,高级一点的特性你可能都需要解决三个平台的麻烦。
到底什么时候才选择跨平台框架
1.写 Linux App 的时候。
2.你的 App 不需要平台特性的时候。
Facebook POP 进阶指南
Facebook 在发布了 Paper 之后,似乎还不满足于只是将其作为一个概念性产品,更进一步开源了其背后的动画引擎 POP (https://github.com/facebook/pop) ,此举大有三年前发布的 iOS UI 框架 Three20 (https://github.com/facebookarchive/three20) 的意味。而 POP 开源后不负 Facebook 的厚望,在 Github 上不足一个月的时间,就已经拥有了 6000+ 个 Star,非常火爆。
POP 背后的开发者是 Kimon Tsinteris (http://kimtsi.com) Push Pop Press 的联合创始人,曾经在 Apple 担任高级工程师,并参与了 iPhone 和 iPad 上软件的研发(iPhone的指南针以及地图)。 2011年的时候 Facebook 收购了他的公司,此后他便加入了 Facebook 负责 Facebook iOS 版本的开发。
如果你打开 Push Pop Press 开发的 AI Gore 这款 App,你会发现交互和动画与 Paper 几乎如出一辙。对,他们都是Kimon Tsinteris 开发的。
不满于 Apple 自身动画框架的单调,Push Pop Press 致力于创造一个逼真的,充满物理效应的体验。POP 就是这个理念下最新一代的成果。
POP 使用 Objective-C++ 编写,Objective-C++ 是对 C++ 的扩展,就像 Objective-C 是 C 的扩展。而至于为什么他们用 Objective-C++ 而不是纯粹的 Objective-C,原因是他们更喜欢 Objective-C++ 的语法特性所提供的便利。
POP 的架构
POP 目前由四部分组成 (图1.1) 1. Animations 2. Engine 3. Utility 4. WebCore
POP 动画极为流畅,其秘密就在于这个 Engine 中的POPAnimator 里,POP 通过 CADisplayLink 高达 60 FPS 的特性,打造了一个游戏级的动画引擎。
CADisplayLink 是类似 NSTimer 的定时器,不同之处在于,NSTimer 用于我们定义任务的执行周期,资料的更新周期,他的执行受到 CPU 的阻塞影响,而 CADisplayLink 则用于定义画面的重绘,动画的演变,他的执行基于 frames 的间隔。
通过 CADisplayLink,Apple 允许你将 App 的重绘速度设定到和屏幕刷新频率一致,由此你可以获得非常流畅的交互动画,这项技术的应用在游戏中非常常见,著名的 Cocos-2D 也应用了这个重要的技术。
WebCore 里包含了一些从 Apple 的开源的网页渲染引擎里拿出的源文件(http://www.opensource.apple.com/source/WebCore),与 Utility 里的组件一并,提供了 POP 的各项复杂计算的基本支持。
由此通过 Engine、Utility、WebCore 三个基石,打造了Animations。
POPAnimation 有着和 CALayer 非常相似的 API。如果你知道 CALayer 的动画 API,那么你对下面的接口一定非常熟悉, 想必你一定开始迫不及待想试试 POP 了,我们现在就 Jump right in。
因为篇幅原因,下面的代码并不是完整代码,你可以到 https://github.com/kevinzhow/pop-handapp 获取我们的示例 App 。
基本类型
Spring Animation
ease-in ease-out 这些可能你已经非常熟悉,这是动画的动作标配了,不过 POP 觉得只是这样显然太无聊,提供了两个非常不同于其的动画模式,第一个就是 Spring Animation。(图 2.1 )
Spring Animation 由诸多的复杂参数来控制,展现了一个非常风骚的姿势。
Bounciness 反弹-影响动画作用的参数的变化幅度
Speed 速度
Tension 拉力-影响回弹力度以及速度
Friction 摩擦力-如果开启,动画会不断重复,幅度逐渐削弱,直到停止。
Mass 质量-细微的影响动画的回弹力度以及速度
Tension,Friction,Mass 这三个参数的作用很微妙,需要你在示例程序里去仔细体会。
使用 Spring Animation 的方式非常简单。
POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY]; anim.toValue = [NSValue valueWithCGPoint:CGPointMake(2.0, 2.0)]; anim.springBounciness = 4.0; anim.springSpeed = 12.0; anim.completionBlock = ^(POPAnimation *anim, BOOL finished) { if (finished) {NSLog(@"Animation finished!");}};
通过 [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY] 我们创建了一个二维平面上分别沿着 X 和 Y 坐标轴进行缩放的动画。
因此我们要使用 toValue 来告诉 POP 我们希望分别缩放几倍,如果你不提供 fromValue,那么 POP 将默认从当前的大小为依据进行缩放。值得一提的是,toValue 这里的值要和动画作用的属性一样的结构。如果我们操作 bounds ,那么这里应该是 [NSValue valueWithCGRect:CGRectMake(0.0, 0.0, 200.0,400.0)]。
completionBlock 提供了一个 Callback,动画的执行过程会不断调用这个 block,finished 这个布尔变量可以用来做动画完成与否的判断。
最后我们使用 pop_addAnimation 来让动画开始生效,如果你想删除动画的话,那么你需要调用 pop_removeAllAnimations 。 与 iOS 自带的动画不同,如果你在动画的执行过程中删除了物体的动画,那么物体会停在动画状态的最后一个瞬间,而不是闪回开始前的状态。
Decay Animation
Decay Animation 就是 POP 提供的另外一个非常特别的动画,他实现了一个衰减的效果。这个动画有一个重要的参数 velocity(速率),一般并不用于物体的自发动画,而是与用户的交互共生。这个和 iOS7 引入的 UIDynamic 非常相似,如果你想实现一些物理效果,这个也是非常不错的选择。
Decay 的动画没有 toValue 只有 fromValue,然后按照 velocity 来做衰减操作。如果我们想做一个刹车效果,那么应该是这样的。图
POPDecayAnimation *anim = [POPDecayAnimation animWithPropertyNamed:kPOPLayerPositionX]; anim.velocity = @(100.0); anim.fromValue = @(25.0); //anim.deceleration = 0.998; anim.completionBlock = ^(POPAnimation *anim, BOOL finished) { if (finished) {NSLog(@"Stop!");}};
这个动画会使得物体从 X 坐标的点 25.0 开始按照速率 100点/s 做减速运动。 这里非常值得一提的是,velocity 也是必须和你操作的属性有相同的结构,如果你操作的是 bounds,想实现一个水滴滴到桌面的扩散效果,那么应该是 [NSValue valueWithCGRect:CGRectMake(0, 0,20.0, 20.0)]
如果 velocity 是负值,那么就会反向递减。
deceleration (负加速度) 是一个你会很少用到的值,默认是就是我们地球的 0.998,如果你开发给火星人用,那么这个值你使用 0.376 会更合适。
Property Animation & Basic Animation
POP 号称可以对物体的任何属性进行动画,其背后就是这个 Property Animation驱动。Spring Animation 和 Decay Animation 都是继承自这个类,接下来我们通过一个 Counting Label 的例子来展现这个神奇的能力。( 图 2.5.0 )
与此同时我们也使用了 Basic Animation,经典的 ease-in-out 此刻发挥了重要的作用,因为我们并不需要计数器的数值进行回弹。
POPBasicAnimation *anim = [POPBasicAnimation animation]; anim.duration = 10.0; anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; POPAnimatableProperty * prop = [POPAnimatableProperty propertyWithName:@"count" initializer:^(POPMutableAnimatableProperty *prop) { prop.readBlock = ^(id obj, CGFloat values[]) { values[0] = [[obj description] floatValue];}; prop.writeBlock = ^(id obj, const CGFloat values[]) { [obj setText:[NSString stringWithFormat:@"%.2f",values[0]]];}; prop.threshold = 0.01;}]; anim.property = prop; anim.fromValue = @(0.0); anim.toValue = @(100.0);
POPBasicAnimation 的 timingFunction 我们定义了动画的方式,慢开慢停。随后通过 POPAnimatableProperty 定义了 POP 如何操作 Label 上的数值。
readBlock 中,obj 就是我们的 Label,values 这个是动画作用的属性数组,其值必须是 CGFloat ,之前我们在 Decay Animation 中操作了 bounds
那么 values[0],values1,values2,values3 就分别对应 CGRectMake(0, 0, 20.0, 20.0) 的 0, 0, 20.0, 20.0
这里我们只需要操作 Label 上显示的文字,所以只需要一个参数。通过 values[0] = [[obj description] floatValue] 我们告诉 POP 如何获取这个值。
相应的我们通过 [obj setText:[NSString stringWithFormat:@"%.2f",values[0]]] 告诉了 POP 如何改变 Label 的属性。
threshold 定义了动画的变化阀值,如果这里使用 1,那么我们就不会看到动画执行时候小数点后面的数字变化。 到此为止,我们的 Counting Label 就完成了,是不是超简单?
实战
PopUp & Decay Move
这个实例中我们介绍下如何将 Decay 动画和用户的操作结合起来,实现一个推冰壶的效果。
首先我们给我们的物体添加个 UIPanGestureRecognizer 的手势操作其,处理方式如下
case UIGestureRecognizerStateChanged: { [self.popCircle.layer pop_removeAllAnimations]; CGPoint translation = [pan translationInView:self.view]; CGPoint center = self.popCircle.center; center.x += translation.x; center.y += translation.y; self.popCircle.center = center; [pan setTranslation:CGPointZero inView:self.popCircle]; break; } case UIGestureRecognizerStateEnded: case UIGestureRecognizerStateCancelled: { CGPoint velocity = [pan velocityInView:self.view]; [self addDecayPositionAnimationWithVelocity:velocity]; break; }
当用户触摸这个冰壶的时候,所有动画会立刻停止,然后跟随用户的手指移动。 通过 [pan velocityInView:self.view]; 我们获取了用户手指移动的速率然后在 addDecayPositionAnimationWithVelocity 中处理动画
POPDecayAnimation *anim = [POPDecayAnimation animationWithPropertyNamed:kPOPLayerPosition]; anim.velocity = [NSValue valueWithCGPoint:CGPointMake(velocity.x, velocity.y)];
当用户松开手之后,冰壶会依照地球的重力在低摩擦的状态下前进逐渐停止。如果想增大摩擦力,你可以把速率乘以一个摩擦系数。
Fly In
在这个实例中,我们介绍下如何结合两个动画。实现一个像 Path 的卡片飞入的效果。(图 2.8.0 )
同样保留了 Decay Move 的效果,你可以甩走这张卡片。
POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerPositionY]; anim.fromValue = @-200; anim.toValue = @(self.view.center.y); POPBasicAnimation *opacityAnim = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerOpacity]; opacityAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; opacityAnim.toValue = @1.0; POPBasicAnimation *rotationAnim = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerRotation]; rotationAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; rotationAnim.beginTime = CACurrentMediaTime() + 0.1; rotationAnim.toValue = @(0);
首先把我们的冰壶变成卡片,旋转一点角度。这里需要注意的是,我们使用了 duration 来定义了 Basic Animation 的执行时间,beginTime 来定义了动画的开始时间。beginTime 接受的是一个以秒为单位的时间,所以我们使用了 CACurrentMediaTime() 获取了当前时间,然后加上了延迟时间。
Transform
这个实例是真的酷极了的效果,我们将实现一个用户点击后播放按钮转换为进度条容器的变形效果。( 图 2.9.0 )
首先我们创建一个进度条,这个真是我最拿手的事情了。(梗请见 PNChart https://github.com/kevinzhow/PNChart )通过 lineCap lineWidth 我们调整进度条的样式,然后使用 UIBezierPath 定义了进度条的走向。
CAShapeLayer *progressLayer = [CAShapeLayer layer]; progressLayer.strokeColor = [UIColor colorWithWhite:1.0 alpha:0.98].CGColor; progressLayer.lineWidth = 26.0; UIBezierPath *progressline = [UIBezierPath bezierPath]; [progressline moveToPoint:CGPointMake(25.0, 25.0)]; [progressline addLineToPoint:CGPointMake(700.0, 25.0)]; progressLayer.path = progressline.CGPath; POPSpringAnimation *scaleAnim = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY]; scaleAnim.toValue = [NSValue valueWithCGPoint:CGPointMake(0.3, 0.3)]; POPSpringAnimation *boundsAnim = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerBounds]; boundsAnim.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 800, 50)]; boundsAnim.completionBlock = ^(POPAnimation *anim, BOOL finished) { if (finished) { UIGraphicsBeginImageContextWithOptions(self.popCircle.frame.size, NO, 0.0); POPBasicAnimation *progressBoundsAnim = [POPBasicAnimation animationWithPropertyNamed:kPOPShapeLayerStrokeEnd]; progressBoundsAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; progressBoundsAnim.toValue = @1.0; progressBoundsAnim.completionBlock = ^(POPAnimation *anim, BOOL finished) {if (finished) {UIGraphicsEndImageContext();}}; [progressLayer pop_addAnimation:progressBoundsAnim forKey:@"AnimateBounds"]; } };
首先是一起进行的 scale 和 bounds 的变化效果,播放按钮将缩小然后改变外形成为进度条的容器,在变形结束后,我们触发进度条的动画。
这里我们使用 UIGraphicsBeginImageContextWithOptions(self.popCircle.frame.size, NO, 0.0); 开启了绘画上下文,动画结束后使用 UIGraphicsEndImageContext(); 清空了绘画上下文。这个主要是影响了画板的大小。
这里我们没有使用 UIGraphicsBeginImageContext() 而是使用 UIGraphicsBeginImageContextWithOptions() 以此获取一个更清晰的绘图效果。
值得关注的 POP 周边
POP-HandApp https://github.com/kevinzhow/pop-handapp 这就是本文的示例App,包含了大量动画的操作方法和上述介绍的实例。
AGGeometryKit-POP https://github.com/hfossli/aggeometrykit-pop 通过 POP 对图片进行变形操作,非常酷。
POP-MCAnimate https://github.com/matthewcheok/POP-MCAnimate POP 的一个封装,可以让你更方便的使用 POP。
Rebound http://facebook.github.io/rebound/ POP 的 Android 部分实现,主要是 Spring 的效果,移植自 Facebook 的rebound-js。
结语
POP 是一个新的里程碑,通过 POP,动画的开发门槛大大降低,并且实现了丰富的属性操作,其倡导的可中断式动画交互会革命性也值得我们仔细研究体会,想必不久就会涌现大量富有活力的 App ,感谢 Facebook,感谢开源。 Long live Opensource.
关于 WWDC 2014 我期待着什么?
iWatch
北京时间 6 月 3 日凌晨 1 点就可以揭晓这个谜底了,但是在这之前我非常的不安,甚至是有点焦躁。于是写这片文章发泄下心里的郁闷。
到目前为止我们已经从 Google 那里得到了很多利好的信息。
软件方面
新版的 Gmail
下一代 Android 系统
硬件方面
Android Wear
Google Glass
Google Silver 高端手机
然而 Apple 这边,最大的猜想就是 iWatch 了,不管到底是 Watch 还是手环,还是项链,还是其他所有你可以想像的 Wear,都不重要,Google Glass 出了之后,这个市场已经非常热闹,基本上用人类的科技,你能想到的穿戴设备都已经有了,你能想像用穿戴设备做的事情,大家都已经在做了,这个东西 Apple 出了,做得再好,都不是一件 Change the world 的事情。
But,仍然有一些这个 iWatch 可以做的非常酷的事情。
集成的 Siri,So 你可以直接控制你的手机。
像 Pebble 那样直接提示你手机上发生的事情,作为一个通知外设,防水,于是这样你不会在洗澡的时候错过你的重要信息,App 的通知信息可以直接调用 Watch 的提醒模式,App 可以读取到 Watch 存在手机里的你的个人数据。
这个手环可以作为遥控器
Watch 这类的穿戴设备,如果你朝着功能方向走,那么就是要做成一个能看,能交互,能获取信息的东西,类似 Gear Fit,但是这个方向的问题是,如果走的通,我们为什么要大屏手机?你愿意为这个东西不停的充电么?
如果你朝着健康类设备走,量化你的一切身体数据,这个方向最有价值的无非是提供一个你量化后的健康状态,智能的了不得了就是自动给你一些健康建议,朝前看一下是能够做自动诊断之类的,这东西只能说是智能手机的一环,并不是生态核心。
但是出了后,我肯定会买的。
iOS 8
毫无疑问,这是不应该缺席的,iOS 7 依旧很多需要改进的地方,那么 iOS 8 到底会改进什么呢?在你接着看之前,我想说 iOS 8 一定是会比较无聊的。
地图,这是毫无疑问需要改进和必然能实现的。
Siri,这个技术,在 iOS 7 最大的改进是,换了套声音,iOS 8 的排期里,这个是真的需要改进的东西,但是,我真不觉得可以做出多大改进,或许她可以分清楚你说“一个小时后叫醒我”这句话不是在问一个叫做“一个小时候的”地方,如果它能理解为我在问《小时代3》的上映时间,我倒是要惊呆了。
通知,每一代 iOS 版本的演进,通知中心都是个值得摆弄的东西,这一代,通知中心应该能多一些方便的操作让你整理通知,然后像 Android 那样可以直接和 App 交互,放心,这里不会出现什么黑科技。
信息,对垃圾短信可以好好防一下了,满足了这个,大家还是会很开心的,Android用户会鄙夷的看,我们早就能让软件浏览我的全部信息,记录我所有通话来帮助我防止垃圾信息了。
相机,毫无疑问,更有趣的拍照技术。
音质,非常好的音质,但是好又怎么样,这个不够屌啊。
分级大屏幕解决方案,当这个系统应用到大屏幕手机里,如过只是单纯的等比放大,没什么意义,因为等比放大只是增加了字体和 UI 大小,却没有增加信息量,你看下 Android 的大屏幕就知道了,并没有增加什么信息量。Apple 如果要解决这个,那么开发者要做的事情就会变得非常复杂,所以我不指望 Apple 会选择等比放大之外的技术,虽然我期待一个分级大屏幕解决方案。
OS X 10.10
对于这个系统,毫无疑问今年是很重要的,是时候做这么一件事情。就是——
开发者可以稍作修改就将它们的 iOS 程序运行在 Mac 上。
这是一个已经完全可行的技术。其他的界面修改,改 UI,提升点体验,Siri 引入进来,都是小儿科的。
iPhone 6
…… 大屏幕,超薄,更快,拍照牛逼,音质爆表,然后?
硬件的更新
Retina Macbook Air, 既然已经续航达到了 12 hr,那么变成 18 hr 没有什么意义,上个 Retina 保持现在的续航,这个设备是很酷的,加上如果 OS X 能运行 iOS 的程序,这款设备还是非常不错的。
Retina Cinema Display 没有就对不起观众了。
Retina iMac 没有就对不起观众了。
希望我的以上所有猜想都是低估了 Apple, Or 即使我 High 起来了,但是还是对 Apple 的未来充满担忧。

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch • No registration required • HD streaming
在沙面偶遇的小姑娘 瞬间抓拍 SONY a6000 is Great!
原来,我三年前的 Blender 水平已经这个样子了,我是为何荒废了这个技能。
AnyConnect 带来 iPhone 上的新生活
假如说我越狱的理由有两个的话,一个是我可以高性能运行像 PPSSPP 这样的模拟器,另外一个就是可以带来 Client 端的分流,更开心的上网。
然而我都没有越狱,7.1 发布后更是没有机会去越狱了。
幸福的是 AnyConnect 改变了我窘迫的现状。
不会断线
可以给客户端下发走 VPN 的路由表
稳定
So,我们来聊一聊如何通过 Ocserv 在 Ubuntu 13.10 搭建你的 AnyConnect。
这里不选择 12.04 的原因是他的包比较旧,需要你很折腾才能编译 Ocserv,另外 14.04 已经 On the way 了。
PS.如果想要在 Ubuntu 12.04 上安装,那么需要参考这文章安装 Nettle 和 Gnutls
安装 Ocserv
下载 Ocserv 0.3.2
wget ftp://ftp.infradead.org/pub/ocserv/ocserv-0.3.2.tar.xz tar xvf ocserv-0.3.2.tar.xz cd ocserv-0.3.2
安装编译依赖
sudo apt-get install build-essential libwrap0-dev libpam0g-dev libdbus-1-dev \ libreadline-dev libnl-route-3-dev libprotobuf-c0-dev libpcl1-dev\ libopts25-dev autogen libgnutls28 libgnutls28-dev libseccomp-dev
编译
./configure --prefix=/usr --sysconfdir=/etc && make && sudo make install
生成证书
这里你需要先仔细阅读官方的文档 简单的来说,如下几步
创建工作文件夹
mkdir CA cd CA
生成 CA 证书
certtool --generate-privkey --outfile ca-key.pem vim ca.tmpl #输入一下内容 cn = "VPN CA" organization = "Big Corp" serial = 1 expiration_days = 3650 ca signing_key cert_signing_key crl_signing_key #保存退出文件编辑 certtool --generate-self-signed --load-privkey ca-key.pem \ --template ca.tmpl --outfile ca-cert.pem
生成本地服务器证书
certtool --generate-privkey --outfile server-key.pem vim server.tmpl # 输入以下内容 cn = "www.example.com" organization = "MyCompany" serial = 2 expiration_days = 3650 encryption_key signing_key tls_www_server #保存退出文件编辑 certtool --generate-certificate --load-privkey server-key.pem \ --load-ca-certificate ca-cert.pem --load-ca-privkey ca-key.pem \ --template server.tmpl --outfile server-cert.pem
生成之后
server-cert.pem 放到/etc/ssl/certs server-key.pem 放到/etc/ssl/private
配置文件
工作目录是最初解压出来的 ocserv-0.3.2
sudo mkdir /etc/ocserv && \ sudo cp doc/sample.config /etc/ocserv/ && \ sudo mv /etc/ocserv/sample.conf /etc/ocserv/ocserv.conf
编辑配置文件
vim /etc/ocserv/ocserv.conf
修改如下
auth = "plain[/etc/ocserv/ocpasswd]" #ocserv支持多种认证方式,这是自带的密码认证,使用ocpasswd创建密码文件 #ocserv还支持证书认证,可以通过Pluggable Authentication Modules (PAM)使用radius等认证方式 #证书路径 server-cert = /etc/ssl/certs/server-cert.pem server-key = /etc/ssl/private/server-key.pem #同一个用户最多同时登陆数 max-same-clients = 10 #运行组 run-as-group = nogroup #分配给VPN客户端的IP段 ipv4-network = 10.10.0.0 #DNS dns = 8.8.8.8 dns = 8.8.4.4 #注释掉route的字段,这样表示所有流量都通过 VPN 发送 #route = 192.168.1.0/255.255.255.0 #route = 192.168.5.0/255.255.255.0
创建用户
sudo ocpasswd -c /etc/ocserv/ocpasswd username #username为你要添加的用户名
修改系统配置,允许转发
vim /etc/sysctl.conf #修改这行 net.ipv4.ip_forward = 1 #保存退出 sysctl -p
修改 iptables 规则 你可以参考 Linode 的文章 来配置 iptables
*filter # Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0 -A INPUT -i lo -j ACCEPT -A INPUT -d 127.0.0.0/8 -j REJECT # Accept all established inbound connections -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Allow all outbound traffic - you can modify this to only allow certain traffic -A OUTPUT -j ACCEPT # Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL). -A INPUT -p tcp --dport 80 -j ACCEPT -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT # Allow SSH connections # # The -dport number should be the same port number you set in sshd_config # -A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT # Allow ping -A INPUT -p icmp -j ACCEPT # Log iptables denied calls -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7 -A INPUT -j DROP COMMIT
特别需要主意的是,一定不要存在这样的一句话 不然能连上也是哪里都不能访问……
-A FORWARD -j DROP #不要存在这句
在你的 /etc/rc.local 的exit 前面加上这句 来开启 NAT
iptables -t nat -A POSTROUTING -j MASQUERADE iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
Debug
现在我们可以开启服务器试试了
sudo ocserv -c /etc/ocserv/ocserv.conf -f -d 1
如果你出现了这样的错误
DBUS connection error (Connection ":1.225" is not allowed to own the service "org.infradead.ocserv" due to security policies in the configuration file)Cannot create command handler
那么你需要这样处理
sudo cp ocserv-0.3.2/doc/dbus/org.infradead.ocserv.conf /etc/dbus-1/system.d/
Thanks to sskaje
拿起你的 iPhone,下载思科的 AnyConnect 客户端
然后输入你的服务器地址,以及你的用户名密码。 出现问题可以看debug的返回信息,如果信息不详细,可以把 1 改成 10
另外也可以通过 ifconfig 来看下你的设备名,我的是 vpns3,然后通过 tcpdump 抓包来看下数据
sudo tcpdump -i vpns3 -vv
配置启动文件
现在我们需要一个脚本来管理 Ocserv
你可以在这里找到, Thanks to Tony
把这个文件复制到 /etc/init.d/ocserv
然后
sudo chmod 755 /etc/init.d/ocserv sudo update-rc.d ocserv defaults
就可以开机启动了。
你也可以通过
/etc/init.d/ocserv start
这样子来管理。
下发路由
我想这个功能是最激动人心的,因为我们手机如果长期连接,那么肯定是某些服务走 VPN,而国内的网站可以走手机自己的网络体验最好。
但是这里的一个问题是,AnyConnect 有下发路由表的 64 条数限制。
所以我们只能保证下某几个常用的服务是可用的,比如 Google Facebook 以及 Twitter
编辑配置文件
sudo vim /etc/ocserv/ocserv.conf
找到 route = 的字段
你可以使用我的路由表,把这些复制到里面。 保存后重新启动 VPN 服务器,就可以了。
/etc/init.d/ocserv restart
另外这里也有一个我写的 ruby 脚本,用来转换 72.52.99.0/24 > 72.52.99.0/255.255.255.0 这样格式的路由 CIDR to Wildcard mask。
这样你可以自行通过 nslookup
nslookup www.google.com
这样来获取服务器的A地址,然后转换成我们需要的格式。
一个可行的方案
如果你有台国内的VPS,那么你可以通过在 VPN 服务器上配置策略路由,来用国内服务器代理国内IP的请求。你可以参考我的 TomatoAutoVPN 来配置这样的特性。
现在我的手机已经连接了 8 个小时,非常愉快的使用着,希望你也能享受这样的快乐。
如果你遇到了任何问题,欢迎回复,我不一定作答。
Written with StackEdit.
让 Nginx SPDY 和 iOS 交朋友
SPDY 这个东西非常酷,昨晚和朋友聊着天突然提到这个东西,就决定给我家 Server 以及 iOS 和 Android 客户端都上一下这个高大上的技术。
Nginx
Nginx 从 1.5.10 开始实现了 draft 3 of SPDY 在 Ubuntu 上直接添加了 Nginx 官方的 development PPA 源,升级后(如果是编译安装的话,请编译时候加 --with-http_spdy_module)就可以支持 SPDY。
你可以通过 nginx -V 这个命令,来看下编译参数有没有 --with-http_spdy_module
配置上来说其实是很简单的,但是 iOS 有个问题,所以我们需要另外指定个端口,这里我选择了 4443 来做 SPDY 和iOS的传输。
server { #dedicated port for iOS aka CocoaSPDY listen 4443 spdy; #port for web browser listen 443 ssl spdy default_server; #say we support spdy v3 add_header Alternate-Protocol 443:npn-spdy/3; #compress header when spdy spdy_headers_comp 1; }
CocoaSPDY
其实这里就解决了最大的问题,SPDY 因为是传输二进制,所以本身就是加密的,iOS上我们因为有 Twitter 开源出来的 CocoaSPDY
根据介绍可以很轻松的使用起来
[SPDYURLConnectionProtocol registerOrigin:@"http://xxx.com:4443"];
记得要将全部 API 请求都使用 http://xxx.com:4443 这样就可走 SPDY 了。
昨晚因为配置 4443 端口的时候开了 ssl,所以一直没成功,今天 Kgen 跟我说不需要加 ssl,才恍然大悟,非常感谢。
Written with StackEdit.
Garageband 来学钢琴真是绝配
入了PX150之后配合 Garageband 来学习,非常轻松畅快。 30 买他课程非常值。
不过内购遇到了点小麻烦,Garageband验证账户资料跳转到商店始终是白色的页面,不能载入。
于是随便点了个程序买一下,验证了下资料就可以正常购买了。
最近Apple各种抽我已经无力吐槽,新技能get Piano

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch • No registration required • HD streaming
iOS7 越狱的正确打开方法
越狱这种事情,如果你只是为了装盗版软件,那么不需要看这个文章,直接打开 evasi0n 然后越狱就好了。
本文的目的是,有一个能用的 Cydia
把系统修改成英文,然后打开越狱软件再越狱即可。 谢谢
SC2 和 古剑奇谭2
其实我已经意识到这个问题,就是我是一个相当的基因学习型的人,要是点技能树就得花时间沁在那个环境里,然后学的很快,代价是忘的也很快。 最近重拾游戏,每天减去一些美剧微博的时间来打会游戏,首选是 StarCraft II,RTS 很久都没玩了,估计是我RPG玩多了,小时候玩红警对这种游戏的基本打法就是,挖矿,防御,升级科技,然后排出半屏幕的兵打一波流。战术微操什么的我手没那么快,懒得去记快捷键。 这次玩 RTS 很悲伤的发现我每分钟只有 19 次操作,完全是 RPG 玩法啊,于是开始记快捷键, BB 是兵营, BR 是气矿什么的,开始微操,点人家飞龙什么的。两天后终于突破 36 次操作每分钟了。哎呀,还是挺不错的。退出游戏后还能按照惯性高速编程一会。 忘记是怎么突然看到古剑奇谭2是即时战斗了,还看到支持手柄,那不错啊,国产单机终于开始不回合了,这容易么。当然单纯指的是两剑这个派系的,某猫上卖36块钱一个数字版激活码,坚定的支持下,然后找来之前死而复生的Thinkpad,接上电视,插上手柄。 这个游戏本身的进步是很大的,无论是从流畅度,还是画面,细节,明显等感受到,有矿有气! 古剑2的即时战斗是进入绝对领域后开打,其实这个挺不错的,有种含蓄美。 玩了会后,找到了儿时玩游戏的乐趣,惊喜,期待,开发团队也用心的埋了一些梗。互联网的打法,都让游戏充满了新鲜的血液。 玩了几天游戏,收获不少。回首往事,玩过的很多游戏都给我烙下了其文化的印记。不过写到这会神志不清了,就这样滚床睡觉吧。
今天 PNChart Hit NO.1 Objective-C repos in Github. and NO.4 in All Languages repos in Github
非常值得纪念的一天,以至于我到处发帖叨叨这件事情。
最后还要在博客上记录一下,有半年多没这么兴奋过了。
前几天我通了个宵 (感谢 童话镇 第二季 的陪伴)开源了 PNChart
在随后的时间 Stars 每天都很多,但是没怎么注意,但是直到今天收到了一封国外友人的邮件,我才直到这件事情 PNChart Hit NO.1 Objective-C repos in Github. and NO.4 in All Languages repos in Github
随后便出现在了Explore的首页
而我也幸运的因为 PNChart 进入了 Developer 的今日 Objective-C 的分类第一,(仅次于 Facebook)总榜第四, 这等殊荣真是吓死我了。
今天这么开心的日子,只想借此机会说一句
Fork Me
https://github.com/kevinzhow/PNChart
如何让工作效率飙升,不寂寞,不劳累
常常一个人呆在房间里觉得寂寞又难耐的。 最近发现了一个神奇的方法可以解决这个事情,那就是,放美剧!
童话镇三季伴我度过了一个星期的时间,这个星期做了很多事情,晚上再也不会觉得累了。
强烈推荐!
超简约,超易用, iOS 图表库 PNChart 开源!
Piner 在不久前要做 Chart 功能的时候,找了半天各种纠结,竟然没有一个好看又简单易用的。
So,我写了这个超简约,超易用,带有动画效果的 Chart 库,已支持 Line 和 Bar 两种模式。
你可以前往 Github 地址一探究竟。
https://github.com/kevinzhow/PNChart
BTW, Fork me

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch • No registration required • HD streaming
RVM + Rubinius + Rails + Puma + Nginx + Capistrano + Ubuntu 12.04 配置方案
怎么出来个这么长的名字 一下午的时间在折腾这个,不过总算解决了 参考 http://tommy.chheng.com/2013/01/23/deploying-a-rails-app-on-nginxpuma-with-capistrano/ 参考 http://natewienert.com/rubinius-plus-puma-plus-chruby-plus-capistrano-on-ubuntu 1.RVM 如果没安装的话先安装RVM
\curl -L https://get.rvm.io | bash -s stable
已经安装的话可以更新下
rvm get head -- auto-dotfiles
2.安装Rubinius
rvm install rbx rvm use rbx --default
编辑 ~/.ruby-version 写上 rbx-2.1.1 (此处视安装的rbx版本而定) 3.Gemfile 添加
gem "puma" gem "rubysl", "~> 2.0", platform: :rbx bundle install
编辑 config/puma.rb
#!/usr/bin/env puma environment 'production' basedir = "path_to_your_app" threads 4,48 bind "unix:///tmp/appname.sock" pidfile "#{basedir}/current/tmp/puma/pid" state_path "#{basedir}/current/tmp/puma/state" preload_app! activate_control_app
5.编辑 nginx.conf 这里只列出了一些和puma有关的部分
upstream appname { server unix:///tmp/appname.sock;} server { listen 80; server_name www.appname.com appname.com; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_redirect off; proxy_pass http://appname; } }
6.Puma控制脚本 从此处获得 https://github.com/puma/puma/tree/master/tools/jungle 我Server用的是 Ubuntu 所以用的 init.d 里的脚本 其操作过程可以见 README.md 这里列一下和RVM配合使用的技巧 在你安装RVM的用户终端,使用 echo $PATH 来获取当前的路径配置 然后,复制,黏贴到 puma 这个脚本 line 18 后
PATH=/usr/local/bin:/usr/local/sbin/:/sbin:/usr/sbin:/bin:/usr/bin:your_path
这样可以解决pumactl找不到这类的问题 同样黏贴到 run-puma 里
PATH=your_path
7.Capistrano 添加下面到最后
namespace :puma do desc "Start Puma" task :start, :except => { :no_release => true } do run "mkdir -p #{current_path}/tmp/puma" run "sudo /etc/init.d/puma start #{application}" end after "deploy:start", "puma:start" desc "Stop Puma" task :stop, :except => { :no_release => true } do run "sudo /etc/init.d/puma stop #{application}" end after "deploy:stop", "puma:stop" desc "Restart Puma" task :restart, roles: :app do run "sudo /etc/init.d/puma restart #{application}" end after "deploy:restart", "puma:restart" desc "create a shared tmp dir for puma state files" task :after_symlink, roles: :app do run "sudo rm -rf #{release_path}/tmp" run "ln -s #{shared_path}/tmp #{release_path}/tmp" end after "deploy:create_symlink", "puma:after_symlink" end
由此就可以使用 cap deploy:restart 来启动 Server 了 这里还有一个问题是,开机自启动。直接按照他们给出的方法可能会无法启动,我的解决方法是在我的home目录写了个脚本 里面有这句
do=$(/bin/bash -i -c -l '/etc/init.d/puma start appname')
#vscocam 阳朔