<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Architecting Life</title>
	<atom:link href="http://xujiwei.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://xujiwei.com/blog</link>
	<description>Just do it</description>
	<lastBuildDate>Thu, 05 Apr 2012 17:19:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>在 Mac App 中支持全屏和文件版本控制</title>
		<link>http://xujiwei.com/blog/support-lion-fullscreen-and-versions-in-map-app/</link>
		<comments>http://xujiwei.com/blog/support-lion-fullscreen-and-versions-in-map-app/#comments</comments>
		<pubDate>Thu, 05 Apr 2012 17:19:13 +0000</pubDate>
		<dc:creator>Xu Jiwei</dc:creator>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Mac OS & iOS]]></category>
		<category><![CDATA[Lion]]></category>
		<category><![CDATA[Mac OS]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Versions]]></category>

		<guid isPermaLink="false">http://xujiwei.com/blog/?p=545</guid>
		<description><![CDATA[前言 在 Mac OS X 10.7 Lion 中，新增了两个特性对用户来说可能比较有用的特性，一个是全屏程序，一个是文件版本控制。 全屏程序可以使用户集中注意力到一个程序上，并且隐藏菜单栏、Dock 等不相关的界面元素，使得工作区最大化，更加有效地利用有限的屏幕空间。 文件版本控制可以让用户在不借助于 Time Machine、Git 或者 SVN 这些工具的时候，也可以轻松恢复文件到之前保存过的版本，防止一些误操作删除了重要内容。 全屏程序 全屏功能可以让程序以全屏方式显示，这样用户可以拥有最大的操作区域，并隐藏与程序无关的视觉元素。 在全屏方式下，Dock 和菜单栏都会自动隐藏，可以通过将鼠标移动到屏幕边缘的方式来重新显示 Dock 或者菜单栏。 目前全屏程序有一个问题是在使用双屏的情况下，有一个屏幕会无法使用，只能显示背景图片，而不能同时使用两个屏幕，或者将另外一个程序全屏在另一个屏幕。 另外，全屏程序切换是使用水平动画切换，对我来说可能动作太大，不是很习惯，这是题外话了。 要设置一个 App 支持全屏很简单，只需要设置对应 Window 的属性即可。 Full Screen 有两种模式，分别为 NSWindowCollectionBehaviorFullScreenPrimary 和 NSWindowCollectionBehaviorFullScreenAuxiliary，其中多数时候只需要使用 NSWindowCollectionBehaviorFullScreenPrimary 即可。 在设置 NSWindowCollectionBehaviorFullScreenPrimary 后，就会在相应的 &#8230;<p class="read-more"><a href="http://xujiwei.com/blog/support-lion-fullscreen-and-versions-in-map-app/">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<h2>前言</h2>

<p>在 Mac OS X 10.7 Lion 中，新增了两个特性对用户来说可能比较有用的特性，一个是全屏程序，一个是文件版本控制。</p>

<p>全屏程序可以使用户集中注意力到一个程序上，并且隐藏菜单栏、Dock 等不相关的界面元素，使得工作区最大化，更加有效地利用有限的屏幕空间。</p>

<p>文件版本控制可以让用户在不借助于 Time Machine、Git 或者 SVN 这些工具的时候，也可以轻松恢复文件到之前保存过的版本，防止一些误操作删除了重要内容。</p>

<h2>全屏程序</h2>

<p>全屏功能可以让程序以全屏方式显示，这样用户可以拥有最大的操作区域，并隐藏与程序无关的视觉元素。</p>

<p>在全屏方式下，Dock 和菜单栏都会自动隐藏，可以通过将鼠标移动到屏幕边缘的方式来重新显示 Dock 或者菜单栏。</p>

<p>目前全屏程序有一个问题是在使用双屏的情况下，有一个屏幕会无法使用，只能显示背景图片，而不能同时使用两个屏幕，或者将另外一个程序全屏在另一个屏幕。</p>

<p>另外，全屏程序切换是使用水平动画切换，对我来说可能动作太大，不是很习惯，这是题外话了。</p>

<p>要设置一个 App 支持全屏很简单，只需要设置对应 Window 的属性即可。</p>

<p><a href="http://xujiwei.com/blog/wp-content/uploads/2012/04/Snip20120406_2.png"><img src="http://xujiwei.com/blog/wp-content/uploads/2012/04/Snip20120406_2.png" alt="" title="Snip20120406_2" width="392" height="476" class="alignnone size-full wp-image-550" /></a></p>

<p>Full Screen 有两种模式，分别为 <code>NSWindowCollectionBehaviorFullScreenPrimary</code> 和 <code>NSWindowCollectionBehaviorFullScreenAuxiliary</code>，其中多数时候只需要使用 <code>NSWindowCollectionBehaviorFullScreenPrimary</code> 即可。</p>

<p>在设置 <code>NSWindowCollectionBehaviorFullScreenPrimary</code> 后，就会在相应的 Window 右上角显示一个全屏按钮，用户通过这个按钮就可以切换程序到全屏方式使用。</p>

<h3>全屏模式切换菜单</h3>

<p>有些时候，为了用户使用方便，需要设置一个快捷键，或者菜单来供用户进行全屏模式的切换，这时，只需要添加一个 NSMenuItem 到主菜单的 View 菜单中，将 selector 连接到 First Responder 的 <code>toggleFullScreen:</code> 即可。</p>

<p><a href="http://xujiwei.com/blog/wp-content/uploads/2012/04/Snip20120406_3.png"><img src="http://xujiwei.com/blog/wp-content/uploads/2012/04/Snip20120406_3.png" alt="" title="Snip20120406_3" width="637" height="282" class="alignnone size-full wp-image-551" /></a></p>

<p>Cocoa 在运行时会自动寻找 View 菜单中 selector 为 <code>toggleFullScreen:</code> 的菜单项目，并根据当前窗体的显示情况来自动更新菜单标题为 Enter Full Screen 或 Exit Full Screen。</p>

<h2>文件版本控制</h2>

<p>在 Lion 中对普通用户来说，一个非常有用的特性就是文件版本控制了。在不需要 Time Machine，不需要 Git、SVN 等版本控制参与的情况下，只需要程序支持这个功能，就可以直接找回编辑过文件的以前版本。</p>

<p>在文件版本控制之后，其实是自动保存功能在起作用，要实现文件版本控制，只需要 Mac App 实现自动保存即可，文件版本的控制会有框架来做，不需要开发者过多参与。</p>

<p>对于 NSDocument based 的 Mac App 来说，要实现文件自动保存，一般情况下，只需要在 NSDocument 的子类中实现以下方法就行了：</p>

<pre><code>+ (BOOL)autosavesInPlace {
    return YES:
}
</code></pre>

<p>当然，这是在 Mac App 中，是以 NSDocument 提供的诸如 <code>- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError</code> 或者 <code>- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName error:(NSError **)outError</code> 来保存文件内容为基础，而不是自己去实现写文件内容到磁盘，那样的话就算有 autosaveInPlace 也是不行的。</p>

<p>另外，同样需要使用 <code>- (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError</code> 等 NSDocument 提供的 API 来获取内容。</p>

<p><a href="http://xujiwei.com/blog/wp-content/uploads/2012/04/Snip20120406_4.png"><img src="http://xujiwei.com/blog/wp-content/uploads/2012/04/Snip20120406_4.png" alt="" title="Snip20120406_4" width="1192" height="592" class="alignnone size-full wp-image-552" /></a></p>

<p>另外，在 NSWindowDelegate 也有一些新的方法，可以控制程序在浏览文件的以往版本时，控制程序窗口的样式，例如大小，设置控件的状态等。例如，在默认情况下，浏览文件以往版本会改变当前文档窗口的大小，而如果不想修改文档窗口大小，只是缩放显示的话，可以在 <code>window:willResizeForVersionBrowserWithMaxPreferredSize:maxAllowedSize:</code> 方法中指定窗口要变化到的目标大小：</p>

<pre><code>- (NSSize)window:(NSWindow *)window willResizeForVersionBrowserWithMaxPreferredSize:(NSSize)maxPreferredFrameSize maxAllowedSize:(NSSize)maxAllowedFrameSize {
    NSSize winSize = [window frame].size;
    return winSize;
}
</code></pre>

<p>NSWindowDelegate 的 <strong>Managing Presentation in Version Browsers</strong> 一节中，还有另外一个 delegate 方法，可以得知当前文档窗口正在进入版本浏览，或者退出版本浏览等状态，从而可以设置界面控件，将一些无关的界面元素隐藏，使用户可以更加清晰的观察到文件不同版本之间的差别。</p>

<p>要实现文件版本控制的支持，开发者并没有很多工作需要做，多数功能已经由框架实现。</p>

<h2>参考资料</h2>

<ul>
<li><a href="http://developer.apple.com/library/mac/#documentation/General/Conceptual/MOSXAppProgrammingGuide/FullScreenApp/FullScreenApp.html">Implementing the Full-Screen Experience</a></li>
<li><a href="http://oleb.net/blog/2011/07/whats-new-for-developers-in-lion-part-1/">What&#8217;s New for Developers in Mac OS X Lion (Part 1)</a></li>
</ul>

<p>&#8211; EOF &#8211;</p>
]]></content:encoded>
			<wfw:commentRss>http://xujiwei.com/blog/support-lion-fullscreen-and-versions-in-map-app/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>开源 GoAgentX 和 dodo</title>
		<link>http://xujiwei.com/blog/opensource-goagentx-and-dodo/</link>
		<comments>http://xujiwei.com/blog/opensource-goagentx-and-dodo/#comments</comments>
		<pubDate>Wed, 28 Mar 2012 05:37:13 +0000</pubDate>
		<dc:creator>Xu Jiwei</dc:creator>
				<category><![CDATA[Develop]]></category>
		<category><![CDATA[Mac OS & iOS]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[goagent]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[PhoneGap]]></category>

		<guid isPermaLink="false">http://xujiwei.com/blog/?p=547</guid>
		<description><![CDATA[把之前做了两个项目开源，放到了 github 上。 dodo dodo 是一个使用 HTML+JS+CSS 编写的待办事项软件，基于 jQuery+jQTouch，通过使用 PhoneGap 封装，可以运行于 iOS、webOS、Android 等各个平台。 这个项目主要是用来学习一下 PhoneGap，以及 jQTouch 和 iScroll 等 WebApp 开发相关的库。 截图： 项目地址：https://github.com/ohdarling/dodo GoAgentX GoAgentX 是一个 goagent 在 Mac OS X 下的图形界面控制软件，方便一般用户在 Mac OS X 上部署、配置和使用 goagent。 截图： 项目地址：https://github.com/ohdarling/GoAgentX &#8211; &#8230;<p class="read-more"><a href="http://xujiwei.com/blog/opensource-goagentx-and-dodo/">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>把之前做了两个项目开源，放到了 github 上。</p>

<h2>dodo</h2>

<p>dodo 是一个使用 HTML+JS+CSS 编写的待办事项软件，基于 jQuery+jQTouch，通过使用 PhoneGap 封装，可以运行于 iOS、webOS、Android 等各个平台。</p>

<p>这个项目主要是用来学习一下 PhoneGap，以及 jQTouch 和 iScroll 等 WebApp 开发相关的库。</p>

<p>截图：</p>

<p><img src="https://github.com/ohdarling/dodo/raw/master/Screenshot.png" alt="dodo截图" /></p>

<p>项目地址：<a href="https://github.com/ohdarling/dodo">https://github.com/ohdarling/dodo</a></p>

<h2>GoAgentX</h2>

<p>GoAgentX 是一个 goagent 在 Mac OS X 下的图形界面控制软件，方便一般用户在 Mac OS X 上部署、配置和使用 goagent。</p>

<p>截图：</p>

<p><img src="https://github.com/ohdarling/GoAgentX/raw/master/Screenshot.png" alt="GoAgentX截图" /></p>

<p>项目地址：<a href="https://github.com/ohdarling/GoAgentX">https://github.com/ohdarling/GoAgentX</a></p>

<p>&#8211; EOF &#8211;</p>
]]></content:encoded>
			<wfw:commentRss>http://xujiwei.com/blog/opensource-goagentx-and-dodo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>高性价比 NAS+HTPC 折腾记</title>
		<link>http://xujiwei.com/blog/cost-performance-nas-htpc/</link>
		<comments>http://xujiwei.com/blog/cost-performance-nas-htpc/#comments</comments>
		<pubDate>Wed, 28 Dec 2011 02:00:47 +0000</pubDate>
		<dc:creator>Xu Jiwei</dc:creator>
				<category><![CDATA[Digital]]></category>
		<category><![CDATA[Lifestyle]]></category>
		<category><![CDATA[AMD]]></category>
		<category><![CDATA[ATI]]></category>
		<category><![CDATA[E350]]></category>
		<category><![CDATA[HDMI]]></category>
		<category><![CDATA[HTPC]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[NAS]]></category>
		<category><![CDATA[OpenMediaVault]]></category>
		<category><![CDATA[XBMC]]></category>

		<guid isPermaLink="false">http://xujiwei.com/blog/?p=528</guid>
		<description><![CDATA[最近组装了一台 NAS+HTPC 合体的机器，自认为还有比较好的性价比，在折腾了两个星期之后，终于差不多搞定所有功能。这台 HTPC 使用 XBMC 作为媒体中心，使用 OpenMediaVault 作为 NAS 系统，这篇博客主要记录 OpenMediaVault 和 XBMC 的安装过程和问题。另外，因为折腾的时候有些地方来来回回搞了好多次，记录的顺序可能并不严谨。 通过 XBMC 可以直接索引所有电影，使用 themoviedb.org 来获取电影海报、介绍、演员等信息，使用 IMDb 来获取电影的评分。使用 OpenMediaVault 来管理存储，设置共享文件夹等。 在设置成功 VA-API 后，XBMC 就可以使用显卡的硬件加速了，在播放 1080P 时，CPU 占用基本在 20% 左右，还算比较不错了。 当然，在一开始我也可以选择使用 Windows 系统，XBMC 也有 Windows 版本，在 Windows &#8230;<p class="read-more"><a href="http://xujiwei.com/blog/cost-performance-nas-htpc/">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>最近组装了一台 NAS+HTPC 合体的机器，自认为还有比较好的性价比，在折腾了两个星期之后，终于差不多搞定所有功能。这台 HTPC 使用 XBMC 作为媒体中心，使用 OpenMediaVault 作为 NAS 系统，这篇博客主要记录 OpenMediaVault 和 XBMC 的安装过程和问题。另外，因为折腾的时候有些地方来来回回搞了好多次，记录的顺序可能并不严谨。</p>

<p>通过 XBMC 可以直接索引所有电影，使用 themoviedb.org 来获取电影海报、介绍、演员等信息，使用 IMDb 来获取电影的评分。使用 OpenMediaVault 来管理存储，设置共享文件夹等。</p>

<p>在设置成功 VA-API 后，XBMC 就可以使用显卡的硬件加速了，在播放 1080P 时，CPU 占用基本在 20% 左右，还算比较不错了。</p>

<p>当然，在一开始我也可以选择使用 Windows 系统，XBMC 也有 Windows 版本，在 Windows 上基本也不用操心驱动程序的事情，而且 Windows 上设置 Samba 共享也是很方便的。</p>

<p>注意：本篇文章都是以 AMD E350 APU 来讲安装过程的，如果你用的主板并不是 E350，或者型号与我使用的不完全一致，可能安装过程会有不同。另外，因为 OpenMediaVault 是基于 Linux 的，所以这需要你懂一些 Linux 知识。</p>

<p>PS. 另外，本篇文章的操作都是直接使用 root 账户进行，如果你在安装的时候使用了非 root 账户，那么多数操作可能需要加 sudo 来运行。</p>

<h2>硬件</h2>

<ul>
<li>机箱：万由 N400 4盘位 NAS 机箱</li>
<li>主板：梅捷 SY-E350-U3M</li>
<li>内存：芝奇 G.Skill DDR3 1333 4G</li>
<li>电源：肯亿 200W 小 1U 电源</li>
<li>系统磁盘：SSK SFD201 USB3.0 16G U盘</li>
</ul>

<p>因为都是在促销，或者优惠的时候购买的，不包邮费总价在 1400 元左右。</p>

<h2>软件</h2>

<ul>
<li>基础系统：Debian Squeeze</li>
<li>NAS 系统：OpenMediaVault</li>
<li>媒体中心：XBMC 10.1 Dharma</li>
</ul>

<h2>安装系统</h2>

<h3>创建 OpenMediaVault 安装盘</h3>

<p>因为是用的 NAS 机箱，上面是没有光驱位的，而且我也没有现成的光驱可以用，因为需要用 U 盘来引导安装系统。</p>

<p>首先需要准备一个 512M 以上的 U 盘，然后从 openmediavault.org 下载最新版本的 OpenMediaVault，再使用下面的命令将镜像恢复到 U 盘上：</p>

<pre><code>sudo dd if=openmediavault_0.2.5_i386.iso of=/dev/disk1 bs=4096
</code></pre>

<p>注意：disk1 是在我的机器上 U 盘所在的位置，另外，在 dd 恢复镜像的时候，要使用 /dev/disk1，而不是 disk1s1，disk1s1 就会将镜像恢复到某个分区而不是整个 U 盘了。</p>

<h3>启动盘注意事项</h3>

<p>因为是用的 USB 3.0 的 U 盘，我在安装系统的时候，把 U 盘插在了 USB 3.0 的接口上，但是在系统安装程序启动之后，USB 3.0 的 U 盘没有自动识别出来，因此要将 USB 3.0 的 U 盘插在 USB 2.0 的口上。</p>

<p>在安装的过程中，可以将 Debian 源的地址修改为网易的源镜像，这样安装软件的速度更快一些，网易源的地址为：</p>

<pre><code>http://mirrors.163.com/debian/
</code></pre>

<h3>安装基本软件</h3>

<p>先安装一些基本的软件，包括 X.org，Gnome，GDM3，Vim 和 less：</p>

<pre><code>apt-get install xorg gnome-core gdm3 vim less
</code></pre>

<p>Gnome 和 GDM3 其实到后面都不会用到，但是在运行一些需要图形界面的工具时，例如 glxinfo、fglrxinfo，就需要有 X 支持了。</p>

<h3>设置 debian-multimedia 源</h3>

<p>为了让一些包默认使用 debian-multimedia 的源，先将 debian-multimedia 的源添加到 <code>/etc/apt/sources.list</code>：</p>

<pre><code>deb http://www.debian-multimedia.org squeeze main non-free 
</code></pre>

<p>并将所有其他源行首添加 # 注释掉，运行 <code>apt-get update</code> 更新源。</p>

<p>在更新完成之后，再将其他源行首的 # 删掉，再次运行 <code>apt-get update</code> 更新源。</p>

<h3>安装 debian-multimedia keyring</h3>

<pre><code>apt-get install debian-multimedia-keyring
</code></pre>

<h3>设置 XBMC 用户</h3>

<p>添加一个用户 xbmc 用户来运行 XBMC：</p>

<pre><code>useradd -m -s /bin/bash xbmc
passwd xbmc
</code></pre>

<h3>设置用户 openmediavault 密码</h3>

<p>在后面的设置过程中，可能需要管理员权限，而这个时候是用的 openmediavault 这个用户，我不清楚这个用户的默认密码是什么，所以需要先设置这个用户的密码：</p>

<pre><code>passwd openmediavault
</code></pre>

<h3>启用 SSH</h3>

<p>在安装完 OpenMediaVault 之后，就可以直接访问它的 Web 界面了，建议启用 SSH 以便直接在本机进行操作，省去使用键盘看着电视操作的麻烦。</p>

<p>OpenMediaVault 默认的管理员用户名为 <code>admin</code>，密码为 <code>openmediavault</code>。</p>

<p><span id="more-528"></span></p>

<h2>安装显卡驱动</h2>

<p>Debian 源里的 ATI 闭源驱动 fglrx 貌似有点问题，因此建议从官方下载后再安装。</p>

<p>官方驱动安装说明：<a href="http://www2.ati.com/relnotes/Catalyst_11.6_Linux_Installer.pdf">http://www2.ati.com/relnotes/Catalyst_11.6_Linux_Installer.pdf</a></p>

<h3>删除默认驱动</h3>

<pre><code>apt-get remove --purge xserver-xorg-video-radeon
apt-get remove fglrx-driver fglrx-control fglrx-glx fglrx-atieventsd fglrx-modules-dkms fglrx-glx-ia32
</code></pre>

<h3>安装编译环境</h3>

<p>官方驱动在安装过程中有一些东西需要编译，因此需要安装一下编译环境，以及相关的依赖包：</p>

<pre><code>apt-get install build-essential ia32-libs linux-headers-$(uname -r)
</code></pre>

<h3>下载并安装显卡驱动</h3>

<p>注意，安装显卡驱动需要在 X 下面进行，因此可以在启动时，登入到 Gnome，用 Gnome 中的 Terminal 来安装。</p>

<p>另外，在登入时，建议选择 root 账号。</p>

<pre><code>wget http://www2.ati.com/drivers/linux/ati-driver-installer-11-12-x86.x86_64.run
chmod +x ati-driver-installer-11-12-x86.x86_64.run
./ati-driver-installer-11-12-x86.x86_64.run
</code></pre>

<p>在安装时，选择自动模式即可，自定义模式似乎有些问题。</p>

<p>在安装完成后，使用 aticonfig 命令来生成默认的 X.org 配置文件：</p>

<pre><code>aticonfig --initial
</code></pre>

<h3>配置视频硬件加速</h3>

<pre><code>apt-get install libkms1
wget http://www.splitted-desktop.com/static/libva/libva//pkgs/amd64/libva1_0.31.1-1+sds5_amd64.deb
wget http://www.splitted-desktop.com/static/libva/xvba-video/xvba-video_0.8.0-1_amd64.deb
dpkg -i libva1_0.31.1-1+sds5_amd64.deb
dpkg -i xvba-video_0.8.0-1_amd64.deb
</code></pre>

<p>设置一下 /etc/environment：</p>

<pre><code>vi /etc/environment
LIBVA_DRIVER_NAME=xvba
LIBVA_DRIVERS_PATH=/usr/lib/va/drivers
</code></pre>

<p>安装完成后，进入到 X，在 Gnome Terminal 里检查是否安装成功：</p>

<pre><code>xbmc@openmediavault:~$ vainfo
libva: libva version 0.31.1-sds1
Xlib:  extension "XFree86-DRI" missing on display ":0.0".
libva: va_getDriverName() returns 0
libva: Trying to open /usr/lib/va/drivers/fglrx_drv_video.so
Xlib:  extension "XFree86-DRI" missing on display ":0.0".
libva: va_openDriver() returns 0
vainfo: VA API version: 0.31
vainfo: Driver version: Splitted-Desktop Systems XvBA backend for VA-API - 0.8.0
vainfo: Supported profile and entrypoints
      VAProfileH264High               : VAEntrypointVLD
      VAProfileVC1Advanced            : VAEntrypointVLD
</code></pre>

<p>这表示视频硬件加速已经安装成功了。</p>

<h2>配置声音以及 HDMI 音频</h2>

<h3>安装声音服务</h3>

<pre><code>apt-get install alsa-base alsamixergui
</code></pre>

<p>要添加 xbmc 用户到 audio 用户组：</p>

<pre><code>usermod -a -G audio xbmc
</code></pre>

<h3>设置 HDMI 音频</h3>

<p>使用 <code>aplay -l</code> 命令，可以列出系统中的声卡，HDMI 音频即是 <code>card 0: Generic [HD-Audio Generic], device 3: ATI HDMI [ATI HDMI]</code>。</p>

<pre><code>root@openmediavault:~# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Generic [HD-Audio Generic], device 3: ATI HDMI [ATI HDMI]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: SB [HDA ATI SB], device 0: ALC887 Analog [ALC887 Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: SB [HDA ATI SB], device 1: ALC887 Digital [ALC887 Digital]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
</code></pre>

<p>记下 card 和 device 后面的数字，这个要写在 <code>/etc/asound.conf</code> 里面，用来配置默认音频：</p>

<pre><code>root@openmediavault:~# vi /etc/asound.conf
pcm.!default {
    type hw
    card 0
    device 3
}
</code></pre>

<h3>取消 HDMI 音频默认静音</h3>

<p>使用 <code>amixer scontrols</code> 命令，可以找出 HDMI 音频的控制器，</p>

<pre><code>root@openmediavault:~# amixer scontrols
Simple mixer control 'IEC958',0
</code></pre>

<p>使用 <code>amixer sset IEC958 unmute</code> 可以来设置音频取消静音：</p>

<pre><code>root@openmediavault:~# amixer sset IEC958 unmute 
Simple mixer control 'IEC958',0
  Capabilities: pswitch pswitch-joined penum
  Playback channels: Mono
  Mono: Playback [on]
</code></pre>

<p>将 <code>amixer sset IEC958 unmute</code> 添加到 /etc/rc.local 可以在系统启动时就取消 HDMI 音频的静音了。</p>

<h2>安装 XBMC</h2>

<h3>使用 mplayer 测试 VA-API</h3>

<p>可以先安装一下 mplayer 来测试 VA-API 是否安装成功：</p>

<pre><code>apt-get install libavformat-dev libavutil-dev libpostproc-dev libswscale-dev libmpeg2-4-dev libass-dev libmpcdec-dev libflac-dev libwavpack-dev python-dev gawk gperf nasm libcwiid1-dev libbluetooth-dev zlib1g-dev libsmbclient-dev libiso9660-dev libssl-dev lsb-release libvdpau-dev libmicrohttpd-dev libmodplug-dev librtmp-dev libcrystalhd-dev curl python-dev libyajl-dev libxtst-dev libfaad-dev yasm subversion libva-dev
wget http://www.splitted-desktop.com/static/libva/mplayer-vaapi/mplayer-vaapi-latest-FULL.tar.bz2
tar xpvf mplayer-vaapi-latest-FULL.tar.bz2
cd mplayer-vaapi-20110127
./checkout-patch-build.sh
cd mplayer-vaapi
make install
</code></pre>

<p>使用 mplayer 测试 vaapi 是否可用：</p>

<pre><code>mplayer -vo vaapi -va vaapi -lavdopts threads=N moviename.mkv
</code></pre>

<p>如果能正常播放，说明 VA-API 安装成功。</p>

<h3>编译安装 XBMC 10.1 Dharma</h3>

<p>安装依赖：</p>

<pre><code>apt-get install debhelper python-support cmake autotools-dev autoconf automake unzip libboost-dev zip libtool libgl1-mesa-dev libglu-dev libglew-dev libmad0-dev libjpeg-dev libsamplerate-dev libogg-dev libvorbis-dev libfreetype6-dev libfontconfig-dev libbz2-dev libfribidi-dev libsqlite3-dev libasound2-dev libpng-dev libpcre3-dev liblzo2-dev libcdio-dev libsdl-dev libsdl-image1.2-dev libsdl-mixer1.2-dev libenca-dev libjasper-dev libxt-dev libxmu-dev libxinerama-dev libcurl4-gnutls-dev libdbus-1-dev libhal-storage-dev libhal-dev libpulse-dev libavahi-common-dev libavahi-client-dev libxrandr-dev libavcodec-dev libavformat-dev libavutil-dev libpostproc-dev libswscale-dev libmpeg2-4-dev libass-dev libmpcdec-dev libflac-dev python-dev gawk gperf libcwiid1-dev libbluetooth-dev zlib1g-dev libsmbclient-dev libboost-thread-dev libiso9660-dev libssl-dev lsb-release libmicrohttpd-dev libmodplug-dev librtmp-dev libcrystalhd-dev curl python-dev libyajl-dev libplist-dev libusb-dev libudev-dev  autopoint libmms-dev libmysqlclient-dev
</code></pre>

<p>下载 XBMC 10.1 Dharma 代码：</p>

<pre><code>wget --no-check-certificate https://nodeload.github.com/xbmc/xbmc/zipball/10.1-Dharma -O xbmc-10.1.zip
unzip xbmc-10.1.zip
cd xbmc-xbmc-9f3aec3
</code></pre>

<p>编译和安装：</p>

<pre><code>./bootstrap
./configure --prefix=/usr/local/xbmc --enable-vaapi
make -j2
sudo make install
</code></pre>

<p>如果需要蓝光导航支持的话，需要加上 libbluray，先编译安装 libbluray 库：</p>

<pre><code>git clone git://git.videolan.org/libbluray.git
cd libbluray/
./bootstrap
./configure --prefix=/usr
make
make install
</code></pre>

<p>那么在前面 configure XBMC 的时候，就要添加 <code>--enable-libbluray</code> 参数：</p>

<pre><code>./configure --prefix=/usr/local/xbmc --enable-vaapi --enable-libbluray
</code></pre>

<h2>配置 XBMC</h2>

<h3>禁用 GDM3</h3>

<p>因为要使用 XBMC 作为默认的 X 界面，所以需要禁用掉 GDM3：</p>

<pre><code>apt-get install chkconfig
chkconfig —level 2345 gdm3 off
</code></pre>

<h3>设置 xbmc 用户自动登录</h3>

<p>编辑 /usr/bin/autologin，填入以下内容：</p>

<pre><code>#!/bin/bash
/bin/login -f xbmc
</code></pre>

<p>并添加可执行权限：</p>

<pre><code>chmod +x /usr/bin/autologin
</code></pre>

<p>编辑 /etc/inittab，找到 <code>1:2345:respawn:/sbin/getty 38400 tty1</code>，修改为：</p>

<pre><code>1:2345:respawn:/sbin/getty -n -l /usr/bin/autologin 38400 tty1
</code></pre>

<h3>设置 xbmc 用户自动启动 XBMC</h3>

<p>编辑 /home/xbmc/.profile，在最后添加以下内容：</p>

<pre><code>PATH=/usr/local/xbmc/bin:$PATH

if [ -z “$DISPLAY" ] &amp;&amp; [ $(tty) == /dev/tty1 ]; then
    startx
fi
</code></pre>

<h3>修正 XBMC 里不能关机、重启、休眠</h3>

<pre><code>apt-get install policykit-1 upower acpi-support
vi /var/lib/polkit-1/localauthority/50-local.d/custom-actions.pkla
## 填入以下内容：
[Actions for xbmc user]
Identity=unix-user:xbmc
Action=org.freedesktop.upower.*;org.freedesktop.consolekit.system.*;org.freedesktop.udisks.*
ResultAny=yes
ResultInactive=no
ResultActive=yes
</code></pre>

<h3>设置 xbmc 用户的 X 初始化文件</h3>

<p>编辑 /home/xbmc/.xinitrc，填入以下内容：</p>

<pre><code>exec /usr/bin/ck-launch-session /usr/bin/dbus-launch --exit-with-session /usr/local/xbmc/bin/xbmc-standalone
</code></pre>

<p>并修改权限：</p>

<pre><code>chown xbmc:xbmc /home/xbmc/.xinitrc
</code></pre>

<h3>修正 XBMC 主题中文的问题</h3>

<p>XBMC 中的多数主题自带的字体都不支持中文显示，因此需要使用一个带中文的字体来替换主题自带的字体，我使用的主题是 Rapier，使用 YaHei.Consolas.1.12.ttf 这个字体来替换主题自带的字体。</p>

<p>先将 YaHei.Consolas.1.12.ttf 复制到主题所在目录的 font 文件夹中：</p>

<pre><code>cp YaHei.Consolas.1.12.ttf /home/xbmc/.xbmc/addons/skin.rapier/fonts
</code></pre>

<p>然后使用 bash 脚本来直接删除原来的字体，并用原来的文件名软连接到新的替换字体：</p>

<pre><code>CN_FONT=YaHei.Consolas.1.12.ttf
for f in `ls *.ttf`; do if [ "$f" != $CN_FONT ]; then rm $f; ln -s $CN_FONT $f; fi; done
</code></pre>

<h3>设置视频硬件加速</h3>

<p>进入“设置》视频》播放”，进行以下设置：</p>

<pre><code>* 取消选中 Allow hardware acceleration (VDPAU)
* 选中 Allow hardware acceleration (VAAPI)
</code></pre>

<p>进入“设置》系统》视频输出”，进行以下设置：</p>

<pre><code>* 垂直空白同步：总是开启
</code></pre>

<h3>设置声音输出</h3>

<p>进入“设置》系统》音频输出”，进行以下设置：</p>

<pre><code>* 音频输出设备：hdmi
* 直通输出设备：hdmi
</code></pre>

<p>另外，由于我的电视不支持“AC3 数字音效”和“DTS 数字音效”，所以也要取消选中这两个选项。</p>

<h3>安装 Web 界面</h3>

<p>我使用 iPhone 来控制 XBMC，试用了几个 Web 界面之后，觉得 wTouch 这个界面用起来比较爽。</p>

<p>首先需要在程序扩展里，安装“Web 界面》wTouch”。</p>

<p>然后在“设置》系统》网络》服务”中进行以下设置：</p>

<pre><code>* 选中“允许通过 HTTP 控制 XBMC”
* 设置“Web 界面”为“wTouch”
* 选中“允许异地程序控制 XBMC”
</code></pre>

<p>在 iPhone 中使用 Safari 打开 XBMC 的 IP + 设置中的端口，例如 192.168.2.100:8080，点击 Safari 底部中间的动作按钮，选择“添加至主屏幕”，这样以后就可以像使用一般应用程序一样来使用 wTouch 来控制 XBMC 了。</p>

<p>wTouch 主要使用触摸来操作，使用还是比较方便的，可以在 wTouch 界面中点击右上角的“Help”，来查看使用帮助。</p>

<h3>XBMC 中文扩展库</h3>

<p>中文扩展库项目地址： <a href="http://code.google.com/p/xbmc-addons-chinese/">http://code.google.com/p/xbmc-addons-chinese/</a>。</p>

<pre><code>cd /home/xbmc
wget http://xbmc-addons-chinese.googlecode.com/files/repository.googlecode.xbmc-addons-chinese.zip
</code></pre>

<p>在扩展中，从 zip 安装</p>

<p>可以自行选择添加需要的扩展，已有扩展列表见 <a href="http://bbs.htpc1.com/thread-76915-1-1.html">http://bbs.htpc1.com/thread-76915-1-1.html</a>。</p>

<h2>其他设置</h2>

<h3>HDMI 输出不能全屏的问题</h3>

<p>先添加一个脚本 /usr/bin/atiscan 来设置 HDMI 输出，脚本来源 <a href="http://www.edmondscommerce.co.uk/linux/ati-underscan-fix-for-linux-ubuntu-etc/">http://www.edmondscommerce.co.uk/linux/ati-underscan-fix-for-linux-ubuntu-etc/</a></p>

<pre><code>#!/bin/bash
#
# Suggest you put this script into you home directory, eg 
# mkdir -p ~/bin
# gedit ~/bin/atiscan
# copy paste this in
# chmod +x ~/bin/atiscan

# CONFIG STUFF YOU WILL EDIT
# You can let the script query you for this stuff, though once you have run it once, 
# suggest you edit the script and hard code the settings
DISPLAY_TYPE='dfp1'
WIDTH=1920  
HEIGHT=1080

# SCRIPT STARTS

if [ "" == "$WIDTH" ]
then
    echo "please enter your display width (eg 1280, 1920 etc)"
    read WIDTH
fi
if [ "" == "$WIDTH" ] 
then
    echo "empty widt, dying"
    exit 1
fi
if [ "" == "$HEIGHT" ]
then
    echo "please enter your display width (eg 1280, 1920 etc)"
    read HEIGHT
fi
if [ "" == "$HEIGHT" ] 
then
    echo "empty height, dying"
    exit 1
fi

# DISPLAY TYPE
if [ "" == "$DISPLAY_TYPE" ] 
then
    echo "First we need to check which type of display it is"
    types="crt1 lvds tv cv tmds1 crt2 tmds2 tmds2i dfp1 dfp2 dfp3 dfp4 dfp5 dfp6"
    for t in $types
    do
        aticonfig --query-dispattrib=$t,positionX  
    done
    echo"

    The one that didnt error is the right one

    If you are running more than one monitor/display then take your pick!

    "
    echo "Please enter the one you want to set to $WIDTH x $HEIGHT"
    read DISPLAY_TYPE   
fi


if [ "" == "$DISPLAY_TYPE" ] 
then
    echo "empty display type, dying"
    exit 1
fi


#POSITION
aticonfig --set-dispattrib=$DISPLAY_TYPE,positionX:0
aticonfig --set-dispattrib=$DISPLAY_TYPE,positionY:0
aticonfig --set-dispattrib=$DISPLAY_TYPE,sizeX:$WIDTH
aticonfig --set-dispattrib=$DISPLAY_TYPE,sizeY:$HEIGHT
</code></pre>

<p>在添加完脚本后，可以让这个 atiscan 在启动 XBMC 之前运行，修改 /home/xbmc/.xinitrc，在 xbmc-standalone 前一行，添加一句 <code>/usr/bin/atiscan</code>，.xinitrc 的内容就会变成像下面这样：</p>

<pre><code>/usr/bin/atiscan
exec /usr/bin/ck-launch-session /usr/bin/dbus-launch --exit-with-session /usr/local/xbmc/bin/xbmc-standalone
</code></pre>

<h3>格式化硬盘为 ext4 时的选项</h3>

<p>如果硬盘只做为电影存储的盘，那么有必要将 block size 设置偏大一些，否则一块 2T 的硬盘，inode 所占的空间大概要在 100GB 左右。</p>

<p>参考：<a href="http://wiki.debian.org.hk/w/Format_disk_as_Ext2,_Ext3_or_Ext4">http://wiki.debian.org.hk/w/Format_disk_as_Ext2,_Ext3_or_Ext4</a></p>

<h3>备份系统</h3>

<p>因为系统是装在 U 盘上的，可以直接在另外的电脑上，或者 PE 系统，使用 GHOST 来备份，也可以使用 tar 命令来将系统分区备份成一个文件：</p>

<pre><code>tar czpvf /backup$(date "+%Y-%m-%d").tar.gz --exclude=/proc --exclude=/media --exclude=/mnt --exclude=/dev --exclude=/sys --exclude=/tmp --exclude=/lost+found --exclude=/backup$(date "+%Y-%m-%d").tar.gz /
</code></pre>

<p>还原时同样使用 tar 命令：</p>

<pre><code>tar -xvpzf /backup.tar.gz -C /
mkdir /proc /lost+found /mnt /sys /media
</code></pre>

<h2>截图欣赏</h2>


<a href='http://xujiwei.com/blog/cost-performance-nas-htpc/omv1/' title='omv1'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/12/omv1-150x150.png" class="attachment-thumbnail" alt="omv1" title="omv1" /></a>
<a href='http://xujiwei.com/blog/cost-performance-nas-htpc/omv2/' title='omv2'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/12/omv2-150x150.png" class="attachment-thumbnail" alt="omv2" title="omv2" /></a>
<a href='http://xujiwei.com/blog/cost-performance-nas-htpc/omv3/' title='omv3'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/12/omv3-150x150.png" class="attachment-thumbnail" alt="omv3" title="omv3" /></a>
<a href='http://xujiwei.com/blog/cost-performance-nas-htpc/omv4/' title='omv4'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/12/omv4-150x150.png" class="attachment-thumbnail" alt="omv4" title="omv4" /></a>
<a href='http://xujiwei.com/blog/cost-performance-nas-htpc/omv5/' title='omv5'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/12/omv5-150x150.png" class="attachment-thumbnail" alt="omv5" title="omv5" /></a>
<a href='http://xujiwei.com/blog/cost-performance-nas-htpc/omv6/' title='omv6'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/12/omv6-150x150.png" class="attachment-thumbnail" alt="omv6" title="omv6" /></a>
<a href='http://xujiwei.com/blog/cost-performance-nas-htpc/screenshot000/' title='screenshot000'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/12/screenshot000-150x150.png" class="attachment-thumbnail" alt="screenshot000" title="screenshot000" /></a>
<a href='http://xujiwei.com/blog/cost-performance-nas-htpc/screenshot001/' title='screenshot001'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/12/screenshot001-150x150.png" class="attachment-thumbnail" alt="screenshot001" title="screenshot001" /></a>
<a href='http://xujiwei.com/blog/cost-performance-nas-htpc/screenshot002/' title='screenshot002'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/12/screenshot002-150x150.png" class="attachment-thumbnail" alt="screenshot002" title="screenshot002" /></a>
<a href='http://xujiwei.com/blog/cost-performance-nas-htpc/screenshot003/' title='screenshot003'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/12/screenshot003-150x150.png" class="attachment-thumbnail" alt="screenshot003" title="screenshot003" /></a>
<a href='http://xujiwei.com/blog/cost-performance-nas-htpc/screenshot004/' title='screenshot004'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/12/screenshot004-150x150.png" class="attachment-thumbnail" alt="screenshot004" title="screenshot004" /></a>
<a href='http://xujiwei.com/blog/cost-performance-nas-htpc/screenshot005/' title='screenshot005'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/12/screenshot005-150x150.png" class="attachment-thumbnail" alt="screenshot005" title="screenshot005" /></a>
<a href='http://xujiwei.com/blog/cost-performance-nas-htpc/screenshot007/' title='screenshot007'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/12/screenshot007-150x150.png" class="attachment-thumbnail" alt="screenshot007" title="screenshot007" /></a>
<a href='http://xujiwei.com/blog/cost-performance-nas-htpc/screenshot008/' title='screenshot008'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/12/screenshot008-150x150.png" class="attachment-thumbnail" alt="screenshot008" title="screenshot008" /></a>


<h2>后记</h2>

<p>其实，XBMC 在 Linux 上使用并不太完美，最不折腾的方案还是用 Windows + XBMC + 远程桌面 来管理，Windows 的共享也不是特别麻烦，特别是作为 HTPC，并不需要特别严格的权限管理。</p>

<p>不过，总算是折腾完了，目前运行也算良好。</p>

<p>希望此文对正在折腾 NAS+HTPC 的你有所帮助。</p>

<h2>参考资料</h2>

<ul>
<li><a href="http://forum.ubuntu.org.cn/viewtopic.php?f=74&amp;t=347684">http://forum.ubuntu.org.cn/viewtopic.php?f=74&amp;t=347684</a></li>
<li><a href="http://blog.punkid.org/2011/04/03/build-home-media-center-on-an-ubuntu-system-with-xbmc/">http://blog.punkid.org/2011/04/03/build-home-media-center-on-an-ubuntu-system-with-xbmc/</a></li>
<li><a href="http://www.debian-multimedia.org/">http://www.debian-multimedia.org/</a></li>
<li><a href="http://forum.ubuntu.org.cn/viewtopic.php?t=10733">http://forum.ubuntu.org.cn/viewtopic.php?t=10733</a></li>
<li><a href="http://apt.nc.hcc.edu.tw/docs/debian_X/06_gdm/gdm.htm">http://apt.nc.hcc.edu.tw/docs/debian_X/06_gdm/gdm.htm</a></li>
<li><a href="http://wiki.ubuntu.org.cn/Gnome%E5%BF%AB%E6%8D%B7%E9%94%AE">http://wiki.ubuntu.org.cn/Gnome%E5%BF%AB%E6%8D%B7%E9%94%AE</a></li>
<li><a href="http://forums.amd.com/forum/messageview.cfm?catid=390&amp;threadid=145785">http://forums.amd.com/forum/messageview.cfm?catid=390&amp;threadid=145785</a></li>
<li><a href="http://support.amd.com/us/gpudownload/windows/previous/11/Pages/radeon_linux.aspx?os=Linux%20x86&amp;rev=11.10">http://support.amd.com/us/gpudownload/windows/previous/11/Pages/radeon_linux.aspx?os=Linux%20&#215;86&amp;rev=11.10</a></li>
<li><a href="http://wiki.xbmc.org/index.php?title=HOW-TO:Install_XBMC_for_Linux_on_Ubuntu_with_a_minimal_installation#xorg.conf_configuration_.28Ati.29">http://wiki.xbmc.org/index.php?title=HOW-TO:Install_XBMC_for_Linux_on_Ubuntu_with_a_minimal_installation#xorg.conf_configuration_.28Ati.29</a></li>
<li><a href="http://wiki.debian.org/AtiHowTo">http://wiki.debian.org/AtiHowTo</a></li>
<li><a href="http://wiki.cchtml.com/index.php/Debian">http://wiki.cchtml.com/index.php/Debian</a></li>
<li><a href="http://www.cyberciti.biz/faq/howto-install-kernel-headers-package/">http://www.cyberciti.biz/faq/howto-install-kernel-headers-package/</a></li>
<li><a href="http://www2.ati.com/relnotes/Catalyst_11.6_Linux_Installer.pdf">http://www2.ati.com/relnotes/Catalyst_11.6_Linux_Installer.pdf</a></li>
<li><a href="http://support.amd.com/us/gpudownload/linux/Pages/radeon_linux.aspx?type=2.4.1&amp;product=2.4.1.3.42&amp;lang=English">http://support.amd.com/us/gpudownload/linux/Pages/radeon_linux.aspx?type=2.4.1&amp;product=2.4.1.3.42&amp;lang=English</a></li>
<li><a href="http://wiki.cchtml.com/index.php/Debian#Removing_Catalyst.2Ffglrx">http://wiki.cchtml.com/index.php/Debian#Removing_Catalyst.2Ffglrx</a></li>
<li><a href="http://wiki.xbmc.org/index.php?title=HOW-TO:Install_XBMC_for_Linux_on_Ubuntu_with_a_minimal_installation#Introduction">http://wiki.xbmc.org/index.php?title=HOW-TO:Install_XBMC_for_Linux_on_Ubuntu_with_a_minimal_installation#Introduction</a></li>
<li><a href="http://wiki.xbmc.org/index.php?title=HOW-TO_set_up_HDMI_audio_on_nVidia_GeForce_G210,_GT220,_or_GT240">http://wiki.xbmc.org/index.php?title=HOW-TO_set_up_HDMI_audio_on_nVidia_GeForce_G210,_GT220,_or_GT240</a></li>
<li><a href="https://wiki.archlinux.org/index.php/Advanced_Linux_Sound_Architecture">https://wiki.archlinux.org/index.php/Advanced_Linux_Sound_Architecture</a></li>
<li><a href="http://forum.xbmc.org/showthread.php?t=99487&amp;page=4">http://forum.xbmc.org/showthread.php?t=99487&amp;page=4</a></li>
<li><a href="http://forums.gentoo.org/viewtopic-t-876339-start-0.html">http://forums.gentoo.org/viewtopic-t-876339-start-0.html</a></li>
<li><a href="http://www.turbolinux.com.cn/turbo/wiki/doku.php?id=%E7%A1%AC%E4%BB%B6%E6%94%AF%E6%8C%81:alsa-utils%E5%B7%A5%E5%85%B7%E5%8C%85%E7%9A%84%E4%BD%BF%E7%94%A8">http://www.turbolinux.com.cn/turbo/wiki/doku.php?id=%E7%A1%AC%E4%BB%B6%E6%94%AF%E6%8C%81:alsa-utils%E5%B7%A5%E5%85%B7%E5%8C%85%E7%9A%84%E4%BD%BF%E7%94%A8</a></li>
<li><a href="https://wiki.archlinux.org/index.php/ATI#HDMI_Audio">https://wiki.archlinux.org/index.php/ATI#HDMI_Audio</a></li>
<li><a href="http://bbs.htpc1.com/thread-58652-1-6.html">http://bbs.htpc1.com/thread-58652-1-6.html</a></li>
<li><a href="http://forum.ubuntu.org.cn/viewtopic.php?t=328927">http://forum.ubuntu.org.cn/viewtopic.php?t=328927</a></li>
<li><a href="http://forum.ubuntu.org.cn/viewtopic.php?t=256841">http://forum.ubuntu.org.cn/viewtopic.php?t=256841</a></li>
<li><a href="http://wiki.xbmc.org/index.php?title=XBMC_for_Linux_specific_FAQ">http://wiki.xbmc.org/index.php?title=XBMC_for_Linux_specific_FAQ</a></li>
<li><a href="http://neio.pixnet.net/blog/post/23093687-debian-%E9%96%8B%E6%A9%9F%E8%87%AA%E5%8B%95%E7%99%BB%E9%8C%84%E6%96%B9%E5%BC%8F">http://neio.pixnet.net/blog/post/23093687-debian-%E9%96%8B%E6%A9%9F%E8%87%AA%E5%8B%95%E7%99%BB%E9%8C%84%E6%96%B9%E5%BC%8F</a></li>
<li><a href="https://wiki.archlinux.org/index.php/Start_X_at_Boot_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)">https://wiki.archlinux.org/index.php/Start_X_at_Boot_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)</a></li>
<li><a href="http://sunlzx.iteye.com/blog/1070579">http://sunlzx.iteye.com/blog/1070579</a></li>
<li><a href="http://wiki.xbmc.org/index.php?title=Ubuntu_Suspend_/_Wake">http://wiki.xbmc.org/index.php?title=Ubuntu_Suspend_/_Wake</a></li>
<li><a href="http://blog.jjgod.org/2010/01/08/organize-movie-collections-with-xbmc/">http://blog.jjgod.org/2010/01/08/organize-movie-collections-with-xbmc/</a></li>
<li><a href="http://wiki.debian.org/rtl819x">http://wiki.debian.org/rtl819x</a></li>
<li><a href="https://wiki.archlinux.org/index.php/Wireless_Setup_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)#WPA.2FWPA2">https://wiki.archlinux.org/index.php/Wireless_Setup_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)#WPA.2FWPA2</a></li>
<li><a href="http://www.pantz.org/software/wpa_supplicant/wirelesswpa2andlinux.html">http://www.pantz.org/software/wpa_supplicant/wirelesswpa2andlinux.html</a></li>
<li><a href="http://blog.chinaunix.net/space.php?uid=20564848&amp;do=blog&amp;id=74795">http://blog.chinaunix.net/space.php?uid=20564848&amp;do=blog&amp;id=74795</a></li>
<li><a href="http://www.linuxquestions.org/questions/linux-software-2/wpa2-with-wpa_supplicant-616557/">http://www.linuxquestions.org/questions/linux-software-2/wpa2-with-wpa_supplicant-616557/</a></li>
<li><a href="http://forum.ubuntu.org.cn/viewtopic.php?f=155&amp;t=314945">http://forum.ubuntu.org.cn/viewtopic.php?f=155&amp;t=314945</a></li>
<li><a href="http://blog.csdn.net/Crob/article/details/3292950">http://blog.csdn.net/Crob/article/details/3292950</a></li>
<li><a href="http://hostap.epitest.fi/gitweb/gitweb.cgi?p=hostap.git;a=blob_plain;f=wpa_supplicant/wpa_supplicant.conf">http://hostap.epitest.fi/gitweb/gitweb.cgi?p=hostap.git;a=blob_plain;f=wpa_supplicant/wpa_supplicant.conf</a></li>
<li><a href="http://www.edmondscommerce.co.uk/linux/ati-underscan-fix-for-linux-ubuntu-etc/">http://www.edmondscommerce.co.uk/linux/ati-underscan-fix-for-linux-ubuntu-etc/</a></li>
<li><a href="http://forums.gentoo.org/viewtopic-t-864327-start-0.html">http://forums.gentoo.org/viewtopic-t-864327-start-0.html</a></li>
<li><a href="http://bbs.htpc1.com/thread-100936-1-1.html">http://bbs.htpc1.com/thread-100936-1-1.html</a></li>
<li><a href="http://bbs.htpc1.com/thread-76915-1-1.html">http://bbs.htpc1.com/thread-76915-1-1.html</a></li>
<li><a href="http://code.google.com/p/xbmc-addons-chinese/">http://code.google.com/p/xbmc-addons-chinese/</a></li>
<li><a href="http://163.23.89.100/~chi/blog/index.php?load=read&amp;id=83">http://163.23.89.100/~chi/blog/index.php?load=read&amp;id=83</a></li>
<li><a href="http://wiki.debian.org.hk/w/Format_disk_as_Ext2,_Ext3_or_Ext4">http://wiki.debian.org.hk/w/Format_disk_as_Ext2,_Ext3_or_Ext4</a></li>
<li><a href="https://github.com/xbmc/xbmc/blob/master/README.linux">https://github.com/xbmc/xbmc/blob/master/README.linux</a></li>
</ul>

<p>&#8211; EOF &#8211;</p>
]]></content:encoded>
			<wfw:commentRss>http://xujiwei.com/blog/cost-performance-nas-htpc/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>推开窗户看世界 — Objective-C之外</title>
		<link>http://xujiwei.com/blog/besides-objective-c/</link>
		<comments>http://xujiwei.com/blog/besides-objective-c/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 10:03:45 +0000</pubDate>
		<dc:creator>Xu Jiwei</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[PhoneGap]]></category>
		<category><![CDATA[Titanium]]></category>

		<guid isPermaLink="false">http://xujiwei.com/blog/?p=527</guid>
		<description><![CDATA[Besides Objective-C View more presentations from Jiwei Xu 引子 App Store 如今正风靡世界，许多人都想尝试去自己开发一个 iOS App，不过苹果官方推荐使用的是 Objective-C 这个语言。而 Objective-C 与 C、Java 之类的语言风格差异有些大，短时间并不容易掌握，又或者许多人只是想尝试开发一个可以运行在 iOS 上的程序而已，不想再去额外去学一门新的语言，那这个时候就可以考虑另外的一些技术来开发 iOS App。 在移动开发领域，得益于现在手机的性能越来越好，浏览器的功能越来越强大，JavaScript 也成为一门很流行的程序开发语言，而对应到 iOS 平台上，也有多种使用 JavaScript 来开发 iOS App 的技术。这次要介绍的三种技术之中，就有两种使用了 JavaScript。 另外，许多开发跨平台移动应用开发的解决方案，首选要支持的就是 iOS，因此在 iOS 这个平台上可以看到很多种不使用 Objective-C 去开发 &#8230;<p class="read-more"><a href="http://xujiwei.com/blog/besides-objective-c/">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<div style="width:425px" id="__ss_10556901"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/ohdarling88/besides-objectivec" title="Besides Objective-C" target="_blank">Besides Objective-C</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/10556901" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe> <div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/ohdarling88" target="_blank">Jiwei Xu</a> </div> </div>

<h2>引子</h2>

<p>App Store 如今正风靡世界，许多人都想尝试去自己开发一个 iOS App，不过苹果官方推荐使用的是 Objective-C 这个语言。而 Objective-C 与 C、Java 之类的语言风格差异有些大，短时间并不容易掌握，又或者许多人只是想尝试开发一个可以运行在 iOS 上的程序而已，不想再去额外去学一门新的语言，那这个时候就可以考虑另外的一些技术来开发 iOS App。</p>

<p>在移动开发领域，得益于现在手机的性能越来越好，浏览器的功能越来越强大，JavaScript 也成为一门很流行的程序开发语言，而对应到 iOS 平台上，也有多种使用 JavaScript 来开发 iOS App 的技术。这次要介绍的三种技术之中，就有两种使用了 JavaScript。</p>

<p>另外，许多开发跨平台移动应用开发的解决方案，首选要支持的就是 iOS，因此在 iOS 这个平台上可以看到很多种不使用 Objective-C 去开发 iOS App 的技术，而且其中技术所编写出来的程序，除了可以在 iOS 上运行之外，还可以运行在 Android 以及其他系统平台上。能少写一份代码，何乐而不为呢～</p>

<h2>不使用 Objective-C</h2>

<p>这次要介绍的是三个不使用 Objective-C 来开发 iOS App 的解决方案：</p>

<ul>
<li><a href="http://www.appcelerator.com/products/titanium-mobile-application-development/">Titanium Mobile</a></li>
<li>PhoneGap(http://phonegap.com)</li>
<li>Mono Touch(http://xamarin.com/monotouch)</li>
</ul>

<p>这三个解决方案各有特点，它们的运行机制也有所不同，至于在开发 iOS App 时选用何种方案，可以根据每种方案不同的特点去选择适合自己的。</p>

<h2>Titanium Mobile</h2>

<p>Titanium Mobile 是 AppCelerator 推出的一个基于 JavaScript 的跨平台移动应用开发技术。通过 Titanium Mobile，可以直接使用 JavaScript 开发能运行于 iOS 和 Android 平台的应用程序，而代码只需要写一次。</p>

<p>Titanium Mobile 是通过将 JavaScript 代码映射到对应平台的 Native Code，在 Titanium Mobile 中操作某一个 UI 对象，或者是其他对象时，实时上是在操作对应平台中实际的 UI 对象，例如使用 Ti.UI.createView() 创建一个视图，它在 iOS 中运行时会实际对应到 UIView，使用 Ti.UI.createTabGroup() 就会对应到 iOS 中的 UITabBarController。这样做的好处就是，可以直接使用 JavaScript 来创建出原生的 UI，而不需要使用额外的代码来让程序 UI 更像系统的 UI。</p>

<p>另外，AppCelerator 在收购了 <a href="http://aptana.com/">Apatna</a> 之后，推出了适用于 Titanium 的 IDE <a href="http://www.appcelerator.com/products/titanium-studio/">Titanium Studio</a>，通过使用 Titanium Studio，可以很方便的创建项目、带智能提示的编辑器，以及很方便的调试项目。</p>

<p>在 Titanium Studio 中调试 iOS 项目时，可以做到单步调试，也就意味着，可以拥有不弱于使用 Xcode 开发项目的体验。断点、单步、变量查看功能一应具全。如果需要发布到 App Store，也可以很方便的通过图形化界面来打包。</p>

<p>当然，使用 Titanium Studio 也需要配合 Xcode 来使用，必须要在安装了 Xcode 的情况下，才可以使用 Titanium Studio 来调试和测试项目。</p>

<p>在 Titanium Studio 推出之前，Titanium Mobile 是靠一个 Developer Tool 来进行打包等操作的，相对比较繁琐，而有了 Titanium Studio 之后，让一切变得简单，我也是从那时开始关注 Titanium Mobile。</p>

<p>对于前端开发工程师来说，只需要理解了 iOS 开发中的一些概念，就可以使用 Titanium Mobile 来开发一个像模像样的 iOS App。并且 Titanium Mobile 实现了 CommonJS 规范，可以很方便来模块化程序代码。</p>

<h2>PhoneGap</h2>

<p>PhoneGap 是一个使用 HTML+CSS+JavaScript 来开发移动 App 的解决方案，使用它来开发 App 只需要有 Web 开发基础即可。它在今年10月份被 Adobe 收购了，然后加入到 Apache Software Foundation 进行孵化。</p>

<p>目前 PhoneGap 已经支持了市面上大多数的智能手机平台，其中就有 iOS。</p>

<p>在我看来，PhoneGap 其实只是提供了一个运行于各种智能手机平台的浏览器的壳，通过这个壳，PhoneGap 的 JavaScript 库可以和系统进行沟通，从而实现在 Web 页面中与系统交互的功能。</p>

<p>因为 PhoneGap 只提供了系统功能的 API 调用，而没有提供任何和界面相关的 API，那么界面就只能自己来折腾了。</p>

<p>幸好开源的世界是强大的，已经有了一堆这样的界面库来供我们选择，像 <a href="http://jqtouch.com/">jQTouch</a>、<a href="http://jquerymobile.com/">jQuery Mobile</a>、<a href="http://www.sencha.com/products/touch">Sencha Touch</a> 之类，都提供了类似于 iOS 的界面组件，可以让我们省去许多界面上的编码工作。</p>

<p>使用浏览器来运行 App 的一个坏处就是：慢。因为整个 App 就是一个网页，如果编码不当，整个程序使用起来体验会比较差，和原生的应用会有很大区别。</p>

<p>在上面提到的几个 UI 框架之中，我比较喜欢的是 jQTouch，它只提供了基本 UI 框架和一些视图切换效果，做出来的程序是一个单页面 App，在整个程序的反应速度上会感觉比较好。不过 jQTouch 也缺少一些常用的组件像对话框，而这些在 jQuery Mobile 和 Sencha Touch 之中又有提供。选择使用哪个框架就要看个人喜好了，它们的网站都提供了在线预览功能</p>

<p>其实，如果用不到系统的 API，只是想把自己的程序包装成一个很像 App 的 App 的话，只要用一用 PhoneGap 提供的壳就行了，它的 API 几乎可以不用看，配合一些 UI 框架可以快速的产出一个 iOS App 来。</p>

<p>当然了，PhoneGap 最大的好处就是，几乎跨了几乎所有的主流智能手机平台，这对于初创团队来说，是迅速推出各个平台客户端的一个好方法。另外 PhoneGap 官方网站也提供了一系列配套服务，例如使用 PhoneGap Build 可以直接编译各个平台的程序安装包，而不需要开发者自己在本地配置每个平台的编译环境。</p>

<h2>Mono Touch</h2>

<p>Mono Touch 是一个使用 C# 来编写跨平台应用的框架，同样支持了 iOS 和 Android 两大平台。</p>

<p>Mono Touch 对于 .NET 程序员来说应该是一个好消息，除了调试，其他的都可以在 Windows 中搞定，调试的时候可以通过在虚拟机里运行 Mac OS X 来解决。Mono Touch 因为是基于 Mono 的，也有个配套的 IDE 可以用：Mono Develop。因为都是 .NET，当然也可以用 Vistual Studio 这个更强大的工具了。</p>

<p>与 Titanium Mobile 和 PhoneGap 不同的是，Mono Touch 如果要编译到设备，或者发布到 App Store 的话，是需要收费的。</p>

<p>另外，因为 Mono Touch 也是编译成可执行代码再部署到设备上的，因此运行速度相对于 PhoneGap 所制作的应用来说，应该会快上一些。</p>

<p>不过 Mono Touch 要收费，并且收费还不是很便宜，可能会影响到它的普及率。</p>

<h2>小结</h2>

<p>在上面讲的三个解决方案之外，还有其他好多大大小小的移动应用开发解决方案，但是用于 iOS 上的解决方案，主要也就是映射代码、或者是包装的形式了，对于应用而不是游戏类型来说，一般都是够用的，在具体选择的时候，也可以根据自己更为熟悉哪种语言，或者框架来挑选。</p>

<p>如果你发现了其他有意思的移动应用开发技术，也可以和我分享一下 :)</p>

<h2>参考资料</h2>

<ol>
<li><a href="http://www.appcelerator.com/products/titanium-mobile-application-development/">http://www.appcelerator.com/products/titanium-mobile-application-development/</a></li>
<li><a href="http://developer.appcelerator.com/apidoc/mobile/latest">http://developer.appcelerator.com/apidoc/mobile/latest</a></li>
<li><a href="http://phonegap.com/about">http://phonegap.com/about</a></li>
<li><a href="https://build.phonegap.com/">https://build.phonegap.com/</a></li>
<li><a href="http://www.mono-project.com/Main_Page">http://www.mono-project.com/Main_Page</a></li>
<li><a href="http://xamarin.com/monotouch">http://xamarin.com/monotouch</a></li>
<li><a href="https://github.com/xamarin/monotouch-samples">https://github.com/xamarin/monotouch-samples</a></li>
<li><a href="http://blog.zhaojie.me/2010/09/develop-ios-app-with-monotouch-in-visual-studio-1.html">http://blog.zhaojie.me/2010/09/develop-ios-app-with-monotouch-in-visual-studio-1.html</a></li>
</ol>

<p>&#8211;EOF&#8211;</p>
]]></content:encoded>
			<wfw:commentRss>http://xujiwei.com/blog/besides-objective-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>使用 node.js + nginx 建设网站</title>
		<link>http://xujiwei.com/blog/build-site-with-nodejs-and-nginx/</link>
		<comments>http://xujiwei.com/blog/build-site-with-nodejs-and-nginx/#comments</comments>
		<pubDate>Sun, 11 Dec 2011 09:41:49 +0000</pubDate>
		<dc:creator>Xu Jiwei</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[nodejs]]></category>

		<guid isPermaLink="false">http://xujiwei.com/blog/?p=525</guid>
		<description><![CDATA[昨天搞定了一个小网站的搭建，用了 node.js，另外为了能在一个 VPS 上搭建多个网站，用了 nginx 作为反向代理。 软件介绍 嗯，从维基上复制了一下～ node.js Node.js是一个事件驱动I/O伺服端JavaScript环境，基于V8。目的是为了提供撰写可扩充网络程式，如web服务。第一个版本由Ryan Dahl于2009年释出，后来，Joyent雇用了Dahl，并协助发展Node.js。 nginx nginx（发音同engine x）是一款由俄罗斯程序员Igor Sysoev所开发轻量级的网页服务器、反向代理服务器以及电子邮件（IMAP/POP3）代理服务器。 cluster 在 node.js 0.6.0 之前，有一个第三方的 node.js 模块 cluster，用来进行多核服务器上运行 node.js，以及提供扩展的支持。但是在 node.js 0.6.0 之后，node.js 本身就提供了 cluster 的支持，另外，第三方的 cluster 也与 node.js 0.6 有兼容性问题。目前 node.js 的稳定版本是 0.6.5，因此需要使用原生的 cluster 来代替第三方的 &#8230;<p class="read-more"><a href="http://xujiwei.com/blog/build-site-with-nodejs-and-nginx/">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>昨天搞定了一个小网站的搭建，用了 node.js，另外为了能在一个 VPS 上搭建多个网站，用了 nginx 作为反向代理。</p>

<h2>软件介绍</h2>

<p>嗯，从维基上复制了一下～</p>

<p><strong>node.js</strong></p>

<blockquote>
  <p>Node.js是一个事件驱动I/O伺服端JavaScript环境，基于V8。目的是为了提供撰写可扩充网络程式，如web服务。第一个版本由Ryan Dahl于2009年释出，后来，Joyent雇用了Dahl，并协助发展Node.js。</p>
</blockquote>

<p><strong>nginx</strong></p>

<blockquote>
  <p>nginx（发音同engine x）是一款由俄罗斯程序员Igor Sysoev所开发轻量级的网页服务器、反向代理服务器以及电子邮件（IMAP/POP3）代理服务器。</p>
</blockquote>

<h2>cluster</h2>

<p>在 node.js 0.6.0 之前，有一个第三方的 node.js 模块 cluster，用来进行多核服务器上运行 node.js，以及提供扩展的支持。但是在 node.js 0.6.0 之后，node.js 本身就提供了 cluster 的支持，另外，第三方的 cluster 也与 node.js 0.6 有兼容性问题。目前 node.js 的稳定版本是 0.6.5，因此需要使用原生的 cluster 来代替第三方的 cluster。</p>

<p>幸好内置的 cluster 也足够简单，如果只是为了多核负载均衡，以及支持即时服务重启的话，只需要写一点的代码就可以完成这些功能了。</p>

<p><strong>server.js</strong></p>

<pre><code>var path = require('path');
var http = require('http');
var cluster = require('cluster');

var NODE_ENV = process.env.NODE_ENV || 'production';
var appName = path.basename(__dirname);
var appPort = 9000;

var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
    process.title = appName + ' master';
    console.log(process.title, 'started');

    // 根据 CPU 个数来启动相应数量的 worker
    for (var i = 0; i &lt; numCPUs; i++) {
        cluster.fork();
    }

    process.on('SIGHUP', function() {
        // master 进程忽略 SIGHUP 信号
    });

    cluster.on('death', function(worker) {
        console.log(appName, 'worker', '#' + worker.pid, 'died');
        cluster.fork();
    });

} else {
    process.title = appName + ' worker ' + process.env.NODE_WORKER_ID;
    console.log(process.title, '#' + process.pid, 'started');

    process.on('SIGHUP', function() {
        // 接收到 SIGHUP 信号时，关闭 worker
        process.exit(0);
    });

    http.Server(function(req, res) {
        res.writeHead(200);
        res.end('Worker ' + process.env.NODE_WORKER_ID);
    }).listen(8000);
}
</code></pre>

<p>运行服务 <code>node server.js</code> ：</p>

<pre><code>nodejs master started
nodejs worker 1 #38928 started
nodejs worker 3 #38930 started
nodejs worker 2 #38929 started
nodejs worker 4 #38931 started
</code></pre>

<p>如果直接 kill 掉某一个 worker，<code>kill 38928</code>：</p>

<pre><code>nodejs worker #38931 died
nodejs worker 5 #38934 started
</code></pre>

<p>可以看到一个新的 worker 会马上启动，这就保证了服务的不间断性。</p>

<h2>Virtual Host 支持</h2>

<p>通常情况下，我们不会在一个 IP 上只部署一个网站。在使用 node.js 时，可以使用 connect 提供的 vhost 支持 Virtual Host，但是，这也限制了服务器只能用 node.js，而不能同时使用其他的服务，例如再安装一个 PHP 服务之类。</p>

<p>这时就可以使用 nginx 的反向代理来解决了，用户在访问网站时，请求先到 nginx 进行处理，如果是 node.js 站点的话，将请求转发到 node.js 的服务，然后再将 node.js 服务的结果返回给用户。</p>

<p>在 nginx 中设置反向代理很简单，一句 <code>proxy_pass</code> 就可以搞定：</p>

<pre><code>server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://localhost:9000;
    }
}
</code></pre>

<p>在添加了 Virtual Host 之后，就可以把一些静态资源，例如 CSS、JavaScript 之类的文件，直接交给 nginx 来处理，而不是什么请求都需要到 node.js 这一层去处理，也省去反向代理这一关的消耗。</p>

<h2>Session 支持</h2>

<p>使用 express 这个 node.js web framework 来创建网站时，可以配合 connect 这个中间件来实现 session 支持。</p>

<p>默认情况下，connect 的 session 是使用内置的内存存储来存放 session 信息，这时如果 node.js 服务一旦重启，所有的 session 信息都会丢失，这对于用户来说不是个好体验，那么我们可以用外部的存储来存放 session 信息，例如 redis。</p>

<p>要让 connect 使用 redis 作为 session 存储的话也是很方便的：</p>

<pre><code>var express = require('express');
var RedisStore = require('connect-redis')(express);

var app = express.createServer(
    express.session({ secret: 'keyboard cat', store : new RedisStore() })
);
</code></pre>

<h2>监测文件改动</h2>

<p>在调试的时候，经常需要重新启动 node.js 以便修改过的文件生效，原来第三方的 cluster 有一个配置项，可以很方便的配置监测时间间隔，文件改动后自动重新启动 worker，但是原生的 cluster 就没有这个功能了，需要自己来实现。</p>

<p>fs 模块提供了 watch 函数，可以方便的监测文件修改，使用这个就可以来实现文件修改后自动重启 woker 功能了。</p>

<pre><code>if (cluster.isMaster) {
    process.title = appName + ' master';
    console.log(process.title, 'started');

    var workers = [];

    // 根据 CPU 个数来启动相应数量的 worker
    for (var i = 0; i &lt; numCPUs; i++) {
        var worker = cluster.fork();
        workers.push(worker.pid);
    }

    process.on('SIGHUP', function() {
        // master 进程忽略 SIGHUP 信号
    });

    // 监测文件改动，如果有修改，就将所有的 worker kill 掉
    fs.watch(__dirname, function(event, filename) {
        workers.forEach(function(pid) {
            process.kill(pid);
        });
    });

    cluster.on('death', function(worker) {
        var index = workers.indexOf(worker.pid);
        if (index != -1) {
            workers.splice(index, 1);
        }
        console.log(appName, 'worker', '#' + worker.pid, 'died');
        worker = cluster.fork();
        workers.push(worker.pid);
    });

}
</code></pre>

<p>这样，每次文件保存之后，node.js 都会自动重启，从而避免了每次保存文件要手动重启服务的麻烦。</p>

<p>当然，在使用监测文件自动重启的时候，最好加上 NODE_ENV 的判断，在 development 的时候才进行自动重启，而 production 的时候使用手动重启就够了。</p>

<h2>小结</h2>

<p>总的来说，使用 node.js 来构建网站还是很方便的，加上 nginx 反向代理之后，与使用 PHP 之前也没有很大的区别，又可以享受到 node.js 的高效。</p>

<p>嗯，就这样了，希望此文对你有所帮助。</p>

<h2>参考资料</h2>

<ol>
<li><a href="http://zh.wikipedia.org/wiki/Node.js">http://zh.wikipedia.org/wiki/Node.js</a></li>
<li><a href="http://nodejs.org/docs/v0.6.5/api/cluster.html">http://nodejs.org/docs/v0.6.5/api/cluster.html</a></li>
<li><a href="http://learnboost.github.com/cluster/">http://learnboost.github.com/cluster/</a></li>
<li><a href="http://expressjs.com/">http://expressjs.com/</a></li>
<li><a href="http://senchalabs.github.com/connect/">http://senchalabs.github.com/connect/</a></li>
<li><a href="http://redis.io/">http://redis.io/</a></li>
</ol>

<p>&#8211;EOF&#8211;</p>
]]></content:encoded>
			<wfw:commentRss>http://xujiwei.com/blog/build-site-with-nodejs-and-nginx/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>iOS App 自定义 URL Scheme 设计</title>
		<link>http://xujiwei.com/blog/ios-app-custom-url-scheme-design/</link>
		<comments>http://xujiwei.com/blog/ios-app-custom-url-scheme-design/#comments</comments>
		<pubDate>Sat, 10 Sep 2011 07:00:40 +0000</pubDate>
		<dc:creator>Xu Jiwei</dc:creator>
				<category><![CDATA[Mac OS & iOS]]></category>
		<category><![CDATA[App]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[URL]]></category>
		<category><![CDATA[淘宝]]></category>
		<category><![CDATA[自定义协议]]></category>

		<guid isPermaLink="false">http://xujiwei.com/blog/?p=510</guid>
		<description><![CDATA[在 iOS 里，程序之间都是相互隔离，目前并没有一个有效的方式来做程序间通信，幸好 iOS 程序可以很方便的注册自己的 URL Scheme，这样就可以通过打开特定 URL 的方式来传递参数给另外一个程序。 例如在 iPad 上浏览网页，并且 iPad 已经安装了 淘宝 HD，那么就打开下面这个链接就会在淘宝 HD 中查看这个商品的详细信息，也可以方便的使用淘宝 HD 进行购买、收藏等操作。 在淘宝 HD 中查看商品“2012西藏卓明谷方舟登舰卡(船票)” 当然，如果你在 Mac OS X 中打开这个链接，或者在没有安装 淘宝 HD 的 iPad 中打开这个链接，会提示没有程序来打开这个链接。 配置 要为 iOS 程序添加自定义协议的支持是一件很方便的事，只需要在程序的 Info.plist 添加一个 URL &#8230;<p class="read-more"><a href="http://xujiwei.com/blog/ios-app-custom-url-scheme-design/">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>在 iOS 里，程序之间都是相互隔离，目前并没有一个有效的方式来做程序间通信，幸好 iOS 程序可以很方便的注册自己的 URL Scheme，这样就可以通过打开特定 URL 的方式来传递参数给另外一个程序。</p>

<p>例如在 iPad 上浏览网页，并且 iPad 已经安装了 <a href="http://itunes.apple.com/app/id438865278?mt=8">淘宝 HD</a>，那么就打开下面这个链接就会在淘宝 HD 中查看这个商品的详细信息，也可以方便的使用淘宝 HD 进行购买、收藏等操作。</p>

<p><a href="taobao://item.taobao.com/item.htm?id=12688928896">在淘宝 HD 中查看商品“2012西藏卓明谷方舟登舰卡(船票)”</a></p>

<p>当然，如果你在 Mac OS X 中打开这个链接，或者在没有安装 淘宝 HD 的 iPad 中打开这个链接，会提示没有程序来打开这个链接。</p>

<h2>配置</h2>

<p>要为 iOS 程序添加自定义协议的支持是一件很方便的事，只需要在程序的 Info.plist 添加一个 URL types 节点就可以了。在这个节点里，可以设置这个程序所支持的自定义协议名称，像 http、ftp 这种，一般我们可以设置为程序英文名称，像淘宝客户端中就设置了 taobao，这样 taobao:// 这个形式的 URL 就会关联到淘宝客户端的 App。</p>

<p><img src="http://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/Art/register_custom_scheme.jpg" alt="Info.plist config" /></p>

<h2>实现</h2>

<p>在 Info.plist 里面设置完 URL types 之后，就可以在程序中处理这类 URL 的打开请求了。</p>

<p>在外部程序中，如果打开了指定自定义协议的 URL，程序中 application delegate 的 application:handleOpenURL: 方法就会被调用，在这个方法里，可以获取到触发这个方法的 URL，可以通过对这个 URL 进行判断，例如根据不同的 Host，不同的 Query String 来执行不同的动作。</p>

<pre><code>- (void)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    NSLog(@"%@", [url absoluteString]);

    // 在 host 等于 item.taobao.com 时，说明一个宝贝详情的 url，
    // 那么就使用本地的 TBItemDetailViewController 来显示
    if ([[url host] isEqualToString:@"item.taobao.com"]) {

        // 这里只是简单地假设 url 形式为 taobao://item.taobao.com/item.htm?id=12345678
        // 先获取要查看的宝贝详情的 itemId
        NSString *itemId = [[url query] substringFromIndex:[[url query] rangeOfString:@"id="].location+3];

        // 使用本地 ViewController 来显示淘宝商品详情
        TBItemDetailViewController *controller = [[TBItemDetailViewController alloc] initWithItemId:itemId];
        [self.navigationController pushViewController:controller animated:YES];
        [controller release];
    }
}
</code></pre>

<h2>淘宝 for iOS</h2>

<p>现在，淘宝 和 淘宝 HD 两个客户端都支持 taobao:// 协议，来打开特定的链接。目前已经支持的有：</p>

<ul>
<li>宝贝详情 <a href="taobao://item.taobao.com/item.htm?id=12688928896">taobao://item.taobao.com/item.htm?id=12688928896</a></li>
<li>宝贝搜索 <a href="taobao://s.taobao.com/?q=iphone">taobao://s.taobao.com/?q=iphone</a></li>
<li>店铺搜索 <a href="taobao://shopsearch.taobao.com/browse/shop_search.htm?q=iphone">taobao://shopsearch.taobao.com/browse/shop_search.htm?q=iphone</a></li>
</ul>

<p>例如，想要在自己的程序中，使用淘宝客户端来显示一个淘宝商品的详情，以支持用户可以直接在 iPhone 上购买，收藏等，就可以使用下面的代码：</p>

<pre><code>- (void)showItemInTaobao4iOS:(NSString *)itemId {
    // 构建淘宝客户端协议的 URL
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"taobao://item.taobao.com/item.htm?id=%@", itemId]];

    // 判断当前系统是否有安装淘宝客户端
    if ([[UIApplication sharedApplication] canOpenURL:url]) {
        // 如果已经安装淘宝客户端，就使用客户端打开链接
        [[UIApplication sharedApplication] openURL:url];
    } else {
        // 否则使用 Mobile Safari 或者内嵌 WebView 来显示
        url = [NSURL URLWithString:[NSString stringWithFormat:@"http://item.taobao.com/item.htm?id=%@", itemId]];
        [[UIApplication sharedApplication] openURL:url];
    }
}
</code></pre>

<p>使用淘宝客户端来打开淘宝链接的好处就是可以让用户更加方便的去购买商品，而不需要再重新登录，或者把用户名密码给了第三方的网站而导致安全隐患。</p>

<h2>扩展性</h2>

<p>在淘宝客户端中，支持的 URL 往往是淘宝网站已经有的链接，这些链接的 QueryString 中所带的参数往往已经满足了使用本地代码显示内容的需要，但是为了扩展性考虑，就需要添加一些额外的参数，并且与原有 QueryString 中不冲突的参数名称。通过这些额外的参数，再实现客户端打开链接时更多的自定义行为。</p>

<p>例如，如果在打开特定 URL，进行一些操作后需要再返回原来的程序，就会需要在 URL 中添加类似于 callback 这样的参数，这样在客户端处理完用户的操作后，可以将用户操作的结果返回给原来的程序，从而实现程序间的通信。</p>

<p>示例：</p>

<pre><code>- (void)buyItemInTaobao4iOS:(NSString *)itemId {
    // 构建淘宝客户端协议的 URL
    NSString *format = @"taobao://item.taobao.com/item.htm?id=%@&amp;_action=buy&amp;_callback=myapp://taobaobuysuccess";
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:format, itemId]];

    // 使用淘宝客户端打开链接
    [[UIApplication sharedApplication] openURL:url];
}
</code></pre>

<p><strong>注意：当前淘宝客户端并不支持这样的调用方式，这里仅是一个示例。</strong></p>

<p>当然，在使用这种方式实现程序间通信的时候，需要考虑检查一下来源 URL 的合法性，防止一些非法的调用造成用户的损失。</p>

<h2>结语</h2>

<p>通过自定义协议地支持，可以将 iOS 程序的一些功能和服务提供给外部程序，也可以实现 Web 和本地应用之间的互相调用。</p>

<p>如果你的 iOS 程序有这些需求的话，那么就可以考虑在 iOS 程序中添加自定义协议的支持了。</p>

<h2>参考资料</h2>

<ol>
<li><a href="http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/StandardBehaviors/StandardBehaviors.html#//apple_ref/doc/uid/TP40007072-CH4-SW50">iOS Application Programming Guide: Implementing Custom URL Schemes</a></li>
</ol>

<p>&#8212; EOF &#8212;</p>
]]></content:encoded>
			<wfw:commentRss>http://xujiwei.com/blog/ios-app-custom-url-scheme-design/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>一个路由器，两种网络，VPN和下载两不误</title>
		<link>http://xujiwei.com/blog/router-with-vpn/</link>
		<comments>http://xujiwei.com/blog/router-with-vpn/#comments</comments>
		<pubDate>Tue, 06 Sep 2011 05:34:23 +0000</pubDate>
		<dc:creator>Xu Jiwei</dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[chnroutes]]></category>
		<category><![CDATA[ip]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[OpenVPN]]></category>
		<category><![CDATA[route]]></category>
		<category><![CDATA[路由器]]></category>

		<guid isPermaLink="false">http://xujiwei.com/blog/?p=514</guid>
		<description><![CDATA[最近在用 Titanium 写一个 Twitter 客户端，因为要用到 OAuth 认证，所以就在手机连接 VPN，但是速度比较慢。刚好想在家里的路由器上加上 OpenVPN，昨天就折腾了一下。 在家里路由器上加上 OpenVPN 的一个主要问题是，家里的网络中还有下载机，而下载的流量是不想通过 VPN 去传输的。虽然 chnroutes 项目的路由表可以让国内的 IP 走直连，国外的 IP 走 VPN，但是 eMule 或者 BT 下载时，难免会连接到国外的用户或者服务器，这个时候也不想去浪费 VPN 的流量。 因为这些，我的想法是在路由器上做判断，如果是从下载机过来流量，就通过直接连接，如果其他机器，例如笔记本，就根据目标 IP 来判断是通过直接连接还是 VPN 来传输。 下载机是通过 LAN 连接到路由器的，本来想按进入流量的设备来判断是否为下载机，后来发现实现比较麻烦，就决定按流量来源 IP 来判断是否为下载机的数据。 准备工作 运行 dd-wrt &#8230;<p class="read-more"><a href="http://xujiwei.com/blog/router-with-vpn/">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>最近在用 <a href="http://www.appcelerator.com">Titanium</a> 写一个 Twitter 客户端，因为要用到 OAuth 认证，所以就在手机连接 VPN，但是速度比较慢。刚好想在家里的路由器上加上 OpenVPN，昨天就折腾了一下。</p>

<p>在家里路由器上加上 OpenVPN 的一个主要问题是，家里的网络中还有下载机，而下载的流量是不想通过 VPN 去传输的。虽然 <a href="http://chnroutes.googlecode.com">chnroutes</a> 项目的路由表可以让国内的 IP 走直连，国外的 IP 走 VPN，但是 eMule 或者 BT 下载时，难免会连接到国外的用户或者服务器，这个时候也不想去浪费 VPN 的流量。</p>

<p>因为这些，我的想法是在路由器上做判断，如果是从下载机过来流量，就通过直接连接，如果其他机器，例如笔记本，就根据目标 IP 来判断是通过直接连接还是 VPN 来传输。</p>

<p>下载机是通过 LAN 连接到路由器的，本来想按进入流量的设备来判断是否为下载机，后来发现实现比较麻烦，就决定按流量来源 IP 来判断是否为下载机的数据。</p>

<h2>准备工作</h2>

<ul>
<li>运行 dd-wrt 的路由器一个，要带有 OpenVPN</li>
<li>OpenVPN 服务器一个，认证方式选择证书认证</li>
<li>Linux 知识若干</li>
</ul>

<p>当然 dd-wrt 并不是必须的，也可以是 openwrt 或者 tomato 之类，只要带有 OpenVPN 就行，如果不带 OpenVPN，就需要在启动过程中去外部下载相关的软件，那就是另外的内容了，暂且不提。</p>

<h2>网络分段</h2>

<p>因为要按 IP 来区分流量是否要走 VPN，因此要先划分一下局域网里要用到的 IP 段。</p>

<p>路由器的 IP 是 192.168.2.1，DHCP 分配范围为 192.168.2.100～149，按照需求将一个 /24 的网段分为三个部分：</p>

<ul>
<li>192.168.2.16~31，此 IP 段的设备流量均走直连</li>
<li>192.168.2.32~63，此 IP 段的设备流量根据目标 IP 判断走直连还是走 VPN</li>
<li>192.168.2.100~149，此 IP 段为 DHCP 分配的 IP 段，流量也根据目标 IP 来判断是否走 VPN</li>
</ul>

<p>因为 DHCP 分配的 IP 并不可控，所以将流量走直接的设备，例如下载机，通过静态 IP 的方式，直接分配一个在 192.168.2.16~32 中固定 IP，可以保证不会连接到有 VPN 的网络。</p>

<h2>路由策略表</h2>

<p>先创建一个用来直连的路由策略表，用来将所有指定 IP 段的流量走直连。</p>

<pre><code># 添加一个路由策略表，此表针对 192.168.2.16/28 IP 段有效
ip rule show | grep "lookup 10" || ip rule add from 192.168.2.16/28 ta 10

# 设置策略表的默认路由
WAN_IP=`ifconfig ppp0 | grep "inet addr" | cut -d ":" -f 2 | cut -d " " -f1`
ip route replace 192.168.2.0/24 dev br0 proto kernel scope link src 192.168.2.1 ta 10
ip route replace 127.0.0.0/8 dev lo  scope link
ip route replace 169.254.0.0/16 dev br0  proto kernel  scope link  src 169.254.255.1
ip route replace default via $WAN_IP dev ppp0 ta 10
</code></pre>

<p>将以上代码保存在 dd-wrt 的 Filewall Script 中，这样在每次 WAN IP 改变的时候，都可以更新这个路由策略表了。</p>

<h2>OpenVPN 配置</h2>

<p>OpenVPN 按默认配置即可，需要注意的是，路由器上的 tun mtu、tun mtu extra 以及 mssfix 需要与服务器一致，或者服务器与路由器上的配置一致。</p>

<p>因为要用到 chnroutes，但是 dd-wrt 中的 OpenVPN 配置并不支持自定义配置，没办法添加 route 选项，因此要把这些选项放到 OpenVPN  服务端的配置文件中，使用 push 指令在连接时推送到客户端来。</p>

<p>例如：</p>

<pre><code>push "route 1.0.0.0 255.255.0.0 net_gateway 5"
</code></pre>

<p>另外一有点需要注意，如果在 dd-wrt 中同时启用了 OpenVPN Daemon，建议将 OpenVPN Daemon 的启动方式设置为“System Startup”而不是“WAN Up”，在我的路由器上，使用“WAN Up”时 OpenVPN Daemon 和 OpenVPN Client 会冲突，导致 OpenVPN Client 启动失败。</p>

<h2>解决 max-routes</h2>

<p>OpenVPN 客户端，默认最多只能添加 100 条路由记录，但是 chnroutes 正常生成的路由表，可能会在 1000 条以上，因此 100 条是远远不够的。</p>

<p>这个可以通过 max-routes 配置项来解决，本来打算这个配置同样从服务端推送过来，但是 OpenVPN 现在并不支持 push &#8220;max-routes 1500&#8243; 这样的指令。</p>

<p>在 dd-wrt 的 OpenVPN 配置中，也没有相应的选项，为了解决这个问题，只能采取一个比较取巧的办法来解决。dd-wrt 中的 OpenVPN 配置都是存在 nvram 中的，在 dd-wrt 启动后，会自动从 nvram 中取 OpenVPN 的相关配置，组合成一个 openvpn.conf，而这个配置除了可以在 dd-wrt 的 Web 界面中修改，还可以直接 SSH 到 dd-wrt 上，直接使用 nvram 命令修改。</p>

<p>在这里要 hack 的配置是 mssfix，当然其他的属性也可以，选择 mssfix 是因这个属性比较简单，改起来方便。</p>

<p>我这里设置了 mssfix 为 1400，另外服务器要推送的路由表为 1300 条左右，直接将 max-routes 设置为 1500，在路由器上运行下面这个指令：</p>

<pre><code>nvram set openvpncl_mssfix="1400
max-routes"
</code></pre>

<p>需要注意的是，一定要分两行来输入，否则生成的 openvpn.conf 中，mssfix 1400 和 max-routes 1500 会在同一行而导致配置失效。</p>

<p>这样在生成的 OpenVPN 配置文件中，就有了 max-routes 选项，服务端也可以正常推送路由表了。</p>

<p>不过这样也有一点坏处，那就是如果再修改了 OpenVPN 配置并保存，会把 mssfix 中的那个回车给去掉，再次导致连接失败。不过 OpenVPN 一旦配置完成，也不会经常改动，倒也不是很大的问题。</p>

<h2>配置 DNSMasq</h2>

<p>一般手机上连接上 WiFi 的时候，设置 DNS 等内容会比较麻烦，而如果不设置 DNS，会导致在手机上解析域名时，使用了国内的 DNS 服务器，而这也会导致一些问题，可以按照 autoddvpn 中的说明，将 DNS 设置为 Google Public DNS 和 OpenDNS：</p>

<pre><code>8.8.8.8
8.8.4.4
208.67.222.222
</code></pre>

<h2>打完收工</h2>

<p>配置完成之后，就可以方便的分配家庭局域网里设备的流量走向了，想要设备的流量走直连，只要分配到 192.168.2.16~31 这个 IP 段就可以了，至于其他的设备，可以使用静态 IP，也可以直接使用 DHCP 分配。</p>

<p>嗯，这样再在真机上调试 Twitter 客户端之类的程序就方便了。</p>

<p>PS. 非常感谢 <a href="http://twitter.com/tjmao">@tjmao</a> 在折腾过程中帮助。</p>

<h2>参考资料</h2>

<ol>
<li><a href="http://code.google.com/p/autoddvpn/wiki/DNSMasq">autoddvpn: DNSMasq</a></li>
<li><a href="http://openvpn.net/index.php/open-source/documentation/manuals/69-openvpn-21.html">OpenVPN 2.1 Manual</a></li>
<li><a href="http://rhcss.blog.51cto.com/672018/133812">linux 高级路由及流量控制总结</a></li>
<li><a href="http://linux.die.net/man/8/ip">ip(8)</a></li>
<li><a href="http://linux.die.net/man/8/route">route(8)</a></li>
<li><a href="http://www.dd-wrt.com/wiki/index.php/Hardware#NVRAM">ddwrt: Hardware</a></li>
</ol>

<p>&#8212; EOF &#8212;</p>
]]></content:encoded>
			<wfw:commentRss>http://xujiwei.com/blog/router-with-vpn/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>淘宝 for iOS 历程</title>
		<link>http://xujiwei.com/blog/taobao-for-ios-evolution/</link>
		<comments>http://xujiwei.com/blog/taobao-for-ios-evolution/#comments</comments>
		<pubDate>Wed, 17 Aug 2011 03:27:38 +0000</pubDate>
		<dc:creator>Xu Jiwei</dc:creator>
				<category><![CDATA[Mac OS & iOS]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[淘宝]]></category>

		<guid isPermaLink="false">http://xujiwei.com/blog/?p=508</guid>
		<description><![CDATA[这是在 淘宝2011技术嘉年华 上讲的关于淘宝 for iOS 开发过程的演示文稿。 View more presentations from ohdarling88. &#8212; EOF &#8212;]]></description>
			<content:encoded><![CDATA[<p>这是在 <a href="http://developerclub.taobao.com/">淘宝2011技术嘉年华</a> 上讲的关于淘宝 for iOS 开发过程的演示文稿。</p>

<div style="width:425px" id="__ss_8875347"><object id="__sse8875347" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=forios-110816221534-phpapp01&#038;stripped_title=for-ios&#038;userName=ohdarling88" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse8875347" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=forios-110816221534-phpapp01&#038;stripped_title=for-ios&#038;userName=ohdarling88" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object><div style="padding:5px 0 12px">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/ohdarling88">ohdarling88</a>.</div></div>

<p>&#8212; EOF &#8212;</p>
]]></content:encoded>
			<wfw:commentRss>http://xujiwei.com/blog/taobao-for-ios-evolution/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>My Book Live 评测</title>
		<link>http://xujiwei.com/blog/my-book-live-evaluation/</link>
		<comments>http://xujiwei.com/blog/my-book-live-evaluation/#comments</comments>
		<pubDate>Mon, 08 Aug 2011 11:04:27 +0000</pubDate>
		<dc:creator>Xu Jiwei</dc:creator>
				<category><![CDATA[Digital]]></category>
		<category><![CDATA[My Book Live]]></category>
		<category><![CDATA[NAS]]></category>
		<category><![CDATA[西数]]></category>
		<category><![CDATA[评测]]></category>

		<guid isPermaLink="false">http://xujiwei.com/blog/?p=502</guid>
		<description><![CDATA[早上到手，开箱照见 My Book Live 开箱照。 之前做过 DS211j 的性能评测，这次也主要做一些传输性能的评测，另外加一些功能介绍。 在很早之前，就关注过西数的 My Book 系列，My Book World Edition 也是带网络接口的，不过价格相对较高，而且性能也是很强，性价比不高。前段时间在 Hi!PDA 看到别人发的 My Book Live 介绍之后就看了一下，目前的价格降到合适的位置，刚好下载机的硬盘坏了，就入手了一个 My Book Live。 基本信息 型号：WDBACG0010HCH-SESN 内核： Linux MyBookLive 2.6.32.11-svn22400 #2 Fri Apr 15 11:08:36 PDT 2011 ppc GNU/Linux &#8230;<p class="read-more"><a href="http://xujiwei.com/blog/my-book-live-evaluation/">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>早上到手，开箱照见 <a href="http://xujiwei.com/blog/2011/08/08/wd-my-book-live-openbox/">My Book Live 开箱照</a>。</p>

<p>之前做过 <a href="http://xujiwei.com/blog/2011/05/29/my-digital-life-performance/">DS211j 的性能评测</a>，这次也主要做一些传输性能的评测，另外加一些功能介绍。</p>

<p>在很早之前，就关注过西数的 My Book 系列，My Book World Edition 也是带网络接口的，不过价格相对较高，而且性能也是很强，性价比不高。前段时间在 Hi!PDA 看到别人发的 My Book Live 介绍之后就看了一下，目前的价格降到合适的位置，刚好下载机的硬盘坏了，就入手了一个 My Book Live。</p>

<h2>基本信息</h2>

<p>型号：WDBACG0010HCH-SESN</p>

<p>内核：</p>

<pre><code>Linux MyBookLive 2.6.32.11-svn22400 #2 Fri Apr 15 11:08:36 PDT 2011 ppc GNU/Linux
</code></pre>

<p>CPU 和 内存：</p>

<pre><code>MyBookLive:~# cat /proc/cpuinfo 
processor   : 0
cpu     : APM82181
clock       : 800.000008MHz
revision    : 28.129 (pvr 12c4 1c81)
bogomips    : 1600.00
timebase    : 800000008
platform    : PowerPC 44x Platform
model       : amcc,apollo3g
Memory      : 256 MB
</code></pre>

<p>默认数据分区格式为 ext4：</p>

<pre><code>/dev/sda4 on /DataVolume type ext4 (rw,noatime,nodelalloc)
</code></pre>

<p>实际可用容量只有 992G，还是用 1K 的进制算的⋯⋯</p>

<pre><code>MyBookLive:~# df -H
Filesystem             Size   Used  Avail Use% Mounted on
tmpfs                   53M      0    53M   0% /lib/init/rw
udev                    11M   6.9M   3.7M  65% /dev
tmpfs                   53M      0    53M   0% /dev/shm
rootfs                 2.1G   1.1G   865M  55% /
tmpfs                   53M   3.4M    50M   7% /tmp
ramlog-tmpfs            21M   2.5M    19M  12% /var/log
/dev/sda4              992G   6.7G   986G   1% /DataVolume
</code></pre>

<p>配置相对来说还不错，像 DS211j 也只有 128M 的内存⋯⋯</p>

<h2>传输速度测试</h2>

<p>传输性能测试环境：</p>

<ul>
<li>My Book Live 1TB</li>
<li>MacBook Pro with SSD</li>
<li>Buffalo WZR-HP-G300NH</li>
<li>网络环境：有线千兆LAN，无线 802.11n @ 130Mbps</li>
<li>测试文件：Mac OS X Lion GM 文件，大小 3.75GB</li>
</ul>

<p>小文件传输基本上和文件个数有关，就不做测试了。</p>

<h3>LAN 上传</h3>

<p><a href="http://xujiwei.com/blog/wp-content/uploads/2011/08/LAN_上传.png"><img src="http://xujiwei.com/blog/wp-content/uploads/2011/08/LAN_上传.png" alt="" title="LAN_上传" width="586" height="317" class="alignnone size-full wp-image-503" /></a></p>

<p>速度基本上稳定在 42MB/s 左右，和</p>

<p><span id="more-502"></span></p>

<h3>LAN 下载</h3>

<p><a href="http://xujiwei.com/blog/wp-content/uploads/2011/08/LAN_下载.png"><img src="http://xujiwei.com/blog/wp-content/uploads/2011/08/LAN_下载.png" alt="" title="LAN_下载" width="586" height="322" class="alignnone size-full wp-image-504" /></a></p>

<p><a href="http://xujiwei.com/blog/wp-content/uploads/2011/08/LAN_下载2.png"><img src="http://xujiwei.com/blog/wp-content/uploads/2011/08/LAN_下载2.png" alt="" title="LAN_下载2" width="590" height="326" class="alignnone size-full wp-image-505" /></a></p>

<p>峰值可以到 110MB/s，多数时候在 60MB/s 以上，可能是因为本机用的是 SSD，导致整个传输过程中偶尔会有断流。</p>

<h3>WiFi 上传</h3>

<p><a href="http://xujiwei.com/blog/wp-content/uploads/2011/08/WiFi_上传.png"><img src="http://xujiwei.com/blog/wp-content/uploads/2011/08/WiFi_上传.png" alt="" title="WiFi_上传" width="577" height="319" class="alignnone size-full wp-image-506" /></a></p>

<p>稳定在 9MB/s 左右</p>

<h3>WiFi 下载</h3>

<p><a href="http://xujiwei.com/blog/wp-content/uploads/2011/08/WiFi_下载.png"><img src="http://xujiwei.com/blog/wp-content/uploads/2011/08/WiFi_下载.png" alt="" title="WiFi_下载" width="583" height="322" class="alignnone size-full wp-image-507" /></a></p>

<p>稳定在 8.2MB/s 左右</p>

<p>总的来说，传输速度基本上满足大多数的需要了，如果是使用千兆局域网，传输速度的限制差不多就是硬盘读写的限制。</p>

<h2>功能</h2>

<p>My Book Live 的用途并不是一个下载机，只是我觉得它的配置和价格可以当作一个下载机而已。</p>

<p>它实际的用途可以算作一个入门级的 NAS，常用功能的都有，支持 Mac OS X 的 Time Machine 备份，也可以通过西数自家的软件来在 Windows 上实现类似 Time Machine 的备份功能。</p>

<p>My Book Live 自带了流媒体服务器，在添加共享的时候，指定是媒体文件夹，可以直接在支持 UPnP 的播放器上识别并播放存放于 My Book Live 中的视频文件。</p>

<p>My Book Live 所使用的系统是 Debian Lenny，而且很方便就可以开启 SSH 功能，这样的话，只要懂 Linux，就可以直接当一台电脑来使用了。</p>

<p>要安装软件可以直接用 Debian 的 apt-get 来安装，像我要拿它来当下载机，那就可以直接</p>

<pre><code>apt-get install amule-daemon rtorrent
</code></pre>

<p>这样就安装了 amule 和 rtorrent 分别用来下载电骡和 BT 的资源。</p>

<h2>附加软件</h2>

<p>西数提供了两款 Mobile App 供有 iPhone 或者 Android 手机的人来存取 My Book Live 上的数据，分别为 Wd 2go 和 WD Photos，升级固件到 02.01.06 版本就可以。</p>

<p>不过西数的 Mobile App 好像没有提供远程访问功能，也就是说，你只能和 My Book Live 在同一个局域网内，才可以使用手机去访问存在里面的数据。</p>

<p>另外，WD SmartWare 可以提供类似 Time Machine 的备份功能，不过好像只有 Windows 版本。</p>

<h2>小结</h2>

<p>总的来说，以 My Book Live 的配置和价格来说，我觉得还是蛮实惠的，而且由于是 Linux 系统，可玩性也不错。</p>

<p>不过 My Book Live 除了以太网接口，没有带其他的接口，算是个小小的遗憾。能有个 USB 接口也好么，以后可以用 USB 扩展一下存储，虽然速度可能不会甚如意。</p>

<p>当然，要完全发挥 My Book Live 的性能，还是得准备一个千兆路由或者交换机，要不然千兆的以太网接口就浪费了。</p>

<h2>参考资料</h2>

<ol>
<li><a href="http://mybookworld.wikidot.com/mybook-live">Hacking WD MyBook World Ed</a></li>
<li><a href="http://highlevelbits.free.fr/index.php?option=com_content&amp;view=section&amp;id=17&amp;Itemid=82&amp;lang=en">Mybook Live Feature Packs</a></li>
<li><a href="http://www.hi-pda.com/forum/viewthread.php?tid=815042">http://www.hi-pda.com/forum/viewthread.php?tid=815042</a></li>
<li><a href="http://www.wdc.com/en/products/products.aspx?id=280">http://www.wdc.com/en/products/products.aspx?id=280</a></li>
<li><a href="http://codebox.org.uk/pages/bitmeterOs">BitMeter OS</a></li>
</ol>

<p>&#8212; EOF &#8212;</p>
]]></content:encoded>
			<wfw:commentRss>http://xujiwei.com/blog/my-book-live-evaluation/feed/</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
		<item>
		<title>WD My Book Live 开箱照</title>
		<link>http://xujiwei.com/blog/wd-my-book-live-openbox/</link>
		<comments>http://xujiwei.com/blog/wd-my-book-live-openbox/#comments</comments>
		<pubDate>Mon, 08 Aug 2011 05:55:47 +0000</pubDate>
		<dc:creator>Xu Jiwei</dc:creator>
				<category><![CDATA[Digital]]></category>
		<category><![CDATA[My Book Live]]></category>
		<category><![CDATA[下载]]></category>
		<category><![CDATA[西数]]></category>

		<guid isPermaLink="false">http://xujiwei.com/blog/?p=491</guid>
		<description><![CDATA[下载机的硬盘快挂了，MSS 是很老的东西，再买块硬盘挂上也不爽，刚好最近看到西数的 My Book Live，配置还不错，刚好入一个当下载机。 不过买了之后才想到，我已经有 DS211j，也可以当下载机⋯⋯不过 My Book Live 配置还不错，可以同时挂更多任务了。 &#8212; EOF &#8212;]]></description>
			<content:encoded><![CDATA[<p>下载机的硬盘快挂了，MSS 是很老的东西，再买块硬盘挂上也不爽，刚好最近看到西数的 My Book Live，配置还不错，刚好入一个当下载机。</p>

<p>不过买了之后才想到，我已经有 DS211j，也可以当下载机⋯⋯不过 My Book Live 配置还不错，可以同时挂更多任务了。</p>


<a href='http://xujiwei.com/blog/wd-my-book-live-openbox/img_0737/' title='方方正正的盒子'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/08/IMG_0737-150x150.jpg" class="attachment-thumbnail" alt="方方正正的盒子" title="方方正正的盒子" /></a>
<a href='http://xujiwei.com/blog/wd-my-book-live-openbox/img_0738/' title='包装盒顶部的二维码可以到西数 My Book Live 的产品页面'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/08/IMG_0738-150x150.jpg" class="attachment-thumbnail" alt="包装盒顶部的二维码可以到西数 My Book Live 的产品页面" title="包装盒顶部的二维码可以到西数 My Book Live 的产品页面" /></a>
<a href='http://xujiwei.com/blog/wd-my-book-live-openbox/img_0739/' title='再来一张'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/08/IMG_0739-150x150.jpg" class="attachment-thumbnail" alt="再来一张" title="再来一张" /></a>
<a href='http://xujiwei.com/blog/wd-my-book-live-openbox/img_0740/' title='继续'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/08/IMG_0740-150x150.jpg" class="attachment-thumbnail" alt="继续" title="继续" /></a>
<a href='http://xujiwei.com/blog/wd-my-book-live-openbox/img_0741/' title='东西不多，很紧凑'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/08/IMG_0741-150x150.jpg" class="attachment-thumbnail" alt="东西不多，很紧凑" title="东西不多，很紧凑" /></a>
<a href='http://xujiwei.com/blog/wd-my-book-live-openbox/img_0742/' title='硬盘盒，光盘，说明书，电源'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/08/IMG_0742-150x150.jpg" class="attachment-thumbnail" alt="硬盘盒，光盘，说明书，电源" title="硬盘盒，光盘，说明书，电源" /></a>
<a href='http://xujiwei.com/blog/wd-my-book-live-openbox/img_0743/' title='这就是主角了'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/08/IMG_0743-150x150.jpg" class="attachment-thumbnail" alt="这就是主角了" title="这就是主角了" /></a>
<a href='http://xujiwei.com/blog/wd-my-book-live-openbox/img_0744/' title='和 My Book 一个样'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/08/IMG_0744-150x150.jpg" class="attachment-thumbnail" alt="和 My Book 一个样" title="和 My Book 一个样" /></a>
<a href='http://xujiwei.com/blog/wd-my-book-live-openbox/img_0745/' title='配了三个电源插头，可以适应不同国家的标准'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/08/IMG_0745-150x150.jpg" class="attachment-thumbnail" alt="配了三个电源插头，可以适应不同国家的标准" title="配了三个电源插头，可以适应不同国家的标准" /></a>
<a href='http://xujiwei.com/blog/wd-my-book-live-openbox/img_0746/' title='手抖了，再来一张'><img width="150" height="150" src="http://xujiwei.com/blog/wp-content/uploads/2011/08/IMG_0746-150x150.jpg" class="attachment-thumbnail" alt="手抖了，再来一张" title="手抖了，再来一张" /></a>


<p>&#8212; EOF &#8212;</p>
]]></content:encoded>
			<wfw:commentRss>http://xujiwei.com/blog/wd-my-book-live-openbox/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.588 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-05-19 09:11:00 -->

