随笔-3  评论-26  文章-0  trackbacks-0
  2008年6月4日

  1、.Net技术将大行其道
  虽然就程序员比例而言,.Net与Java还有一定的差距,但在微软操作系统的支持与WPF等新技术推动下,越来越多程序员与企业开始选择.Net技术。个人认为,.Net相对Java最大的优势在于语言的统一性。如是我是老板,招一批.Net程序员,后台程序会做了,前端的富客户端(Silverlight)也会做了,而且.Net入门可比Java快多了,毕竟是微软的技术,易上手啊,谁让我们从小就用微软的东西。
  而在桌面软件方面,.Net则有更大的优势。因为Vista与Vienna将是微软下一代主流操作系统,它们可以天然就带了.Net runtime的。如果这两个操作系统得以普及,.Net技术也将在桌面软件领域大行其道,就这一点,Java是无法望其项背的。
  那相对C++呢,我想过不了几年,硬件水平将有很大提升,摩尔定律就是这样说的,C++所谓的高性能也将不再是核心优势,想必能运行Vista或Vienna的机器,.Net程序也不在话下吧。而.Net开发的快捷与内存安全将成为与C++等非托管语言竞争的杀手锏。
  我们熟知的飞信、Fiddler等大众桌面软件就已经是.Net开发的了。据悉,电信、网通也将陆续推出基于.Net技术的大型客户端软件。.Net的春天指日可待。
  随便说一句,在WPF与Silverlight等技术成熟的时候,.Net与Java也就相当于今天的C++了。
 

  2、OpenID-网络用户集中认证
  相信每个网民都有不下一个的网络ID,新浪的,网易的,yahoo的,Hotmail的,如果要享受某个网站的服务,我就得先注册成它的会员,并且不同网站的用户之间的通信也存在障碍。
  如果能有一个通用的帐号,能在各个网站畅通无阻,这将大大提高用户的上网体验,也没必要记那么多的帐号与密码了。
  这事最闹心了,本来我在各大网站的用户名都是snowwolf的,可在某些网站,也不知谁先给抢注了,我就只得改用snowwolflibo,结果是上网时,我也不知道哪些用户是snowwolf,哪些用户是snowwolflibo。
  现在好了,有了OpenID(据说是微软,Google,Yahoo等力挺的一个概念,具体是什么,我也说不清,反正很拽),各网站可以把用户认证管理托付给另一专注于OpenID服务的系统,实现整个互联网的单点登录。
  除了网站,IM工具的互通互联也势在必行,看看现在的白领一族,每天打开电脑第一件事就是启动各大IM工具,QQ/MSN/Fetion,据说现在又有了百度Hi。我们的桌面早已凌乱不堪了。
  当然IM与网站的集中认证的推行瓶颈不在技术,而是商业层面的东西。所谓的互联可能会先在市场份额小的产商中进行,如百度Hi就宣称要支持互联。但互联也可能出现在大产商对小产商的并购中。这听起来有点像战国时代的“合众”与“连横”。

 
  3、互联网的高度分化
  据说Facebook、Myspace等Web2.0网站已经支持插件扩展了,往大了说,它们已具有互联网平台的雏形了。这点与操作系统极其类似。Windows就是一个开放的平台,基于该平台的API,第三方软件产商可以开发各种应用。而如今(或者说不久将来),互联网也将具备该特性。
  之前互联网倡导的开放、共享、自由仅限于内容领域--我做一个网站,用户可以在上面share各自的文章、相片、视频。而未来的互联网,将极好地实现应用与服务的可扩展化。
  设想一下,未来的互联网产商大致分为四类:
  平台产商:类似Windows、Linux等,它们仅提供网络应用的“插座”,实现数据、界面、通讯、安全等基础逻辑。
  应用产商:类似Office、QQ、SQL Server等应用软件,它们基于平台API编程,实现丰富的网络应用。
  内容产商:利用RSS等技术向网络应用提供内容。
  权限提供商:类似于前面说的OpenID。为整个互联网提供统一的权限认证与用户资料管理。
  而前三者就类似于移动服务的运营商、SP、CP。三者专注于各自领域,联合起来为用户提供内容与服务,并合理分成。
  到那时,新浪之类的网站将不复存在,取而代之的是一个开放的基础平台(网络操作系统,姑且这么说),几个新闻浏览器、视频播放器、博客服务中心,与来源于各大内容提供商的丰富资讯、视频、音频等。
 
  4、社区门户--小区生活的网络延伸
  打开新浪,弹出一个深圳楼盘打折的信息,价格十分诱人,但我看一眼就关掉了。为什么,不关我事啊,咱是要在北京定居的。
  这就是传统门户的弱点,它的内容与广告不具针对性,盲目投放,关注率与消费行为转化率极低。既增加了用户的反感度,也损失了广告主的利益,同时浪漫带宽。
  而我们要做的,是将用户按区域细分。区域可以是按省、市、县,甚至街道,小区。这类新的网络模式我们暂称其为“社区门户”。如果可以精确到小区,社区门户将为不同小区用户提供更对口的服务与内容。
  比如说,小区附近哪的购物最便利,哪有健身房,谁谁谁发起了一场篮球赛,这些信息比传统的信息大杂绘对用户更具实际意义。
  个人觉得,最具建设“社区门户”能力的是电信等运营商。因为他们在宽带接入时就知道了用户的确切位置。
 
  5、定向门户--仅为您提供服务
  如果说“社区门户”是根据区域对用户进行了细分,那“定向门户”则根据身份、职业甚至喜欢为用户量身定制。
  用户向网站发起请求后,网站将依照用户IP、Cookie等参量分析该用户特性,比如说某某某,男,IT从业人士,酷爱数码产品,NBA粉丝,喜欢爱田由与小仓优子(举个例子,看官勿对号入座),持有大量中石油股票。接下来,系统将优先推送与上述特殊相近信息与广告。
  而谁来捕获和分析用户特性?这就是下面要说的内容。
 
  6、提供用户喜好--搜索引擎下一个赢利点
  请先避开个人隐私等法律问题。仅就技术和网络需求而言,提供用户喜好将成为搜索引擎与其合作产商的一大金矿。上面提到的“定向门户”可以为用户提供个性化的服务与内容,而对用户特性偏好最为了解的莫过了Google 百度等搜索引擎。
  而定向门户则可以通过搜索引擎的接口获取当前用户特性,从而推送定向业务。
  就技术而言。搜索引擎基于IP或Cookie或Mac地址等个性化参数存储用户搜索行为。特性分析系统将依据用户搜索行为提炼出用户特征。然后通过WebService等远程技术向定向门户系统公开接口。商业上,两者可进行利益分成。
 
  7、跨终端--大互联网时代来临
  咱也凑个热闹,说说云计算。
  个人觉得,云计算将数据与计算交付给了网络,就存在离线操作的问题,要解决该问题,就必须实现强大的数据与应用的同步功能。就这点而言,云计算要走的路还很长,太虚。
  但另一方面,云计算可以将PC、手机、手表、汽车(此处可大胆想象,个人觉得一切皆可互联)等设备全部纳入网络,这实现了数据与应用在不同设备上的共享。在此咱称之为“跨终端”(我杜撰的),而我们日常生活中的各种器材将与传统的PC、手机一起,进入一个崭新的“大互联网”时代(再次杜撰)。
  设想这样一个场景。我通过PC在网络上找到了一首歌曲,点击“加入收藏”,回到车里,我只要通过汽车的终端设置点击“我的收藏夹”就可以找到该歌曲了。
  还有,记得比尔.盖茨也说过,将来要让房子变得与电脑一样。也许就是这个意思。
 
  完了。欢迎拍我。
posted @ 2008-06-04 13:06 snowwolflibo 阅读(33) | 评论 (0)编辑
  2008年4月25日

  近期在赶一个客户的项目,采用Silverlight技术制作一个视频播放页面。目前版本基于SL 2 Beta 1开发,已初步完Demo版,现将开发所得经验分享如下:
  效果图:

(播放视频)



(鼠标放在缩略图上,显示相关说明)



(鼠标放在视频名称上,显示相关说明)



(点击缩略图视频“翻跟头”进入播放区)



(点击缩略图视频“翻跟头”进入播放区)


页面浏览:http://cms.huadublog.cn/VodSL/VodSLTestPage.html


SL自定义控件经验分享

1、VideoPlayer视频播放控件
  该控件主要功能有Play/Pause/Stop等,这些功能我认为比较简单,在此不提。主要说说如果通过Slider控件实现播放进度条的方法。
  首先创建MediaElement与Slider。
  然后分析下进度条的实现原理:
    A、如何实现Slider与播放进度的同步?答:为MediaElement设置TimelineMarker,将MarkerReached时修改Slider进度值。注意,一定要在MediaElement.MediaOpened事件中添加TimelineMarker。因为添加TimelineMarker要考虑影片的实际长度,比如说,如果想在Slider上设置100个点,那每一点代表的时间就是影片总长度的1/100。看看我的代码:

            this.slider.Minimum = 0;
            
this.slider.Maximum = 100;
            
double seconds = this.mediaElement1.NaturalDuration.TimeSpan.TotalSeconds;
            
for (int i = (int)this.slider.Minimum; i < (int)this.slider.Maximum; i++)
            
{
                TimelineMarker marker 
= new TimelineMarker();
                
double time = seconds / this.slider.Maximum * i;
                marker.Time 
= new TimeSpan(00, (int)time);
                marker.Text 
= "a";
                marker.Type 
= "Test";
                
this.mediaElement1.Markers.Add(marker);
            }

  在此需要注意的是,一定要设置marker.Type,否则您试试,一运行程序就崩溃了。呵呵。
  好了,接下来在MediaElement.MarkerReached事件中添加以下代码:

            double time= e.Marker.Time.TotalSeconds;
            
double seconds= this.mediaElement1.NaturalDuration.TimeSpan.TotalSeconds;
            
if (seconds <= 0)
            
{
                
return;
            }

            
double marker = (time * this.slider.Maximum / seconds);
            txtSlider.Text 
= e.Marker.Time.Hours + ":" + e.Marker.Time.Minutes + ":" + e.Marker.Time.Seconds;
            
this.slider.Value = marker;

  在此,我们根据当前Marker的时间点与总时长算出播放时间占总时间的比例,然后计算出Slider当前应该的进度值。就OK了,如果要显示当前时长的话,只要txtSlider.Text = e.Marker.Time.Hours + ":" + e.Marker.Time.Minutes + ":" + e.Marker.Time.Seconds;即可。

  然后我们再实现进度条的拖拽功能。
  在Slider.ValueChanged事件中添加以下代码:

            double seconds = this.mediaElement1.NaturalDuration.TimeSpan.TotalSeconds;
            
double time = seconds / this.slider.Maximum * this.slider.Value;
            mediaElement1.Position 
= new TimeSpan(00,(int) time);

  一切搞定!
  不过细心的你可能会发现一个问题,那就是MediaElement.MarkerReaded可以改变Slider.Value,而Slider.Value的改变又会引发Slider.ValueChanged,该事件中又有MediaElement.Position=v,这又会引发MediaElement.MarkerReaded,呵呵,死循环吧,没关系,自己加一个信号变量就行了。这我不再详述了。
  

posted @ 2008-04-25 14:58 snowwolflibo 阅读(234) | 评论 (1)编辑
  2008年4月22日

   自Silverlight(以下称SL)1.0 Alpha发布一来,一直对该技术备加关注,加上项目组正好有用到该技术,所以对SL也有了一定程度的了解。SL是一种强大的RIA技术,但同时由于其产品的不成熟,存在很多困扰开发者的问题。不论是对中文的支持,还是对媒体播放的支持,还是对WebService的支持,SL都没能提供很好的解决方案。(当然SL2 Beta 1对中文支持已经很好了)。其实本人一直看好SL,但所谓爱之越深,恨之越切,在此就仅对SL 2Beta 1的不足之处作个说明。当然,如果有不对之处,还请博友们指正。

  Silverlight 2 Beta 1版本缺陷列表

  1、WebService不支持同步调用
        在SL工程中添加Service Reference后,自动生成代理类ServiceSoapClient,实例化ServiceSoapClient后,我们只能看到异步调用的方法。比如,我的WebService提供了一个GetVideoTypes方法,在ServiceSoapClient中却只有GetVideoTypesAsync与GetVideoTypesCompleted,前者是异步方法,后者是相应的事件。上网找了资料,发现在有的外国论坛上,有人也提出了这个问题。

  2、WebRequest不支持同步调用
   与WebService一样,WebRequest也不支持同步,具体不再详述。在此说一下,WebRequest在System.Net.dll中,大家在开发时要自动引用一下。

  3、System.Runtime.Serialization.Json.DataContractJsonSerializer方法不友好
   在SL2 Beta 1中用JSON,我只想说,这是一个比较奢侈的要求,目前MS封闭的System.Runtime.Serialization.Json.DataContractJsonSerializer类接口函数很不友好,只支持ReadObject与WriteObject,没有我期待的Serialize与Deserialize。呵呵,你看看ReadObject接受的参数是什么,Stream!!哈哈,你还要构造一个Stream,而如果在分布式系统中,这个Stream就要从WebRequest与WebResponse得到了,嘿嘿,这两类还不支持同步调用。麻烦啊。不过我记得早期版本是有Serialize与Deserialize的,不知道是给去掉了,还是我没找到。
  BTW,System.Runtime.Serialization.Json.DataContractJsonSerializer在System.ServiceModel.Web.dll中,很不好找啊。

  4、对相对路径支持很不好
  我有一个视频播放的页面,要动态加载一些图片,一开始这可把我难住了。因为SL是客户端执行的,而这些图片是在服务器上。我在Xaml中直接写相对路径如"images/1.png",不好使。为什么呢,我觉得也是可以理解嘛,毕竟SL在客户端执行,客户端哪有这个文件,但你SL的Runtime是不是应该动态的去服务器把这图片download下来啊。我记得老版本是可以的啊。没办法,我一开始只能写完整的uri,如http://localhost/vodsl/images/1.png。
  不过还有一个奇怪的现象,在同一个SL页面中,有的图片显示不出来(如果用相对路径的话),但有的图片又可以显示。My God,想来想去,答案是:SL还是做了动态下载,只不过这个下载可能在SL渲染后完成,就是说有的图片下载不赶趟了。

  
   5、重绘SilderBar控件会让你抓狂
  SL 2 Beta 1引入了TextBox Button ScrollBar等控件,值得夸奖,毕竟在1.1时,自己封装TextBox 还麻烦了(绝对地狱似的编程)。
  而这些控件在美观上是远远不能满足人们日益增长的审美要求的。于是乎,我想重绘它们。感谢SL为我们提供了重绘控件的机制。具体方法是为控件(如:Button ScrollBar)指定Style,这个Style其实就是一个Resource,你可以直接在Xaml中写。但要写在相应控件的前面,否则在运行时,SL会认为控件的Style是一个无效对象。
  但定义这一个Style可不简单耶!!看看SDK中的例子,那是相当长的一段代码。而且你很难知道控件的各个元素叫什么名(我是通过SDK/Google才知道的)。很不人性啊。其实我就是想改一个小滑块的样式,(ScrollBar中的小滑块),就要写一大堆Xaml。大家可以试试,我是花了很长时间才明白这大堆Xaml的具体含义。
  好了,终于可以自定义ScrollBar的样式了,但发现ScrollBar总有一个背景图去不掉,就是下面这个图片:

  无论我怎么修改Style,这个底图总存在。没办法,我最近只好放弃重绘ScrollBar。

  6、说说Grid与DataGrid
  Grid是SL的一个相对定位容器,在Grid中的控件是不能绝对定位的,如果你也与我一样试图在Blend中拖动Grid中的控件,一定感触颇深。我觉得这是很合理的,Grid就像Html中的Table,可用作页面整体的布局,事实上SL的很多控件(比如ScrollBar)内部也是用Grid布局的。但Grid没有提供Rows.Add与Columns.Add等接口,在想动态放置子控件时比较不方便。但Grid引入了RowDefinition与ColumnDefinition的概念,这个我个人比较喜欢。它实现了Grid布局定义与子控件放置的分离,你先定义Grid有几行几列,然后在后面加子控件,再为这些子控件指定Grid.Row与Grid.Column,这样就避免了HTML Table中的层层嵌套。这样的缺陷就是不代码不直观。
  BTW,Grid的单元格似乎不能自动随子控件撑大,我只看到了Maxheight与MinHeight属性,但似乎不能实现这个功能。
  DataGrid居然没有Rows.Add接口,但有Columns.Add接口。

  7、有些属性要通过SetValue与GetValue方法
   .Net 3.0与SL引入了DependencyProperty机制,很好很强大,我们可以在一个类中定义属性,然后别的对象也能用这个属性,没有明白?比如说在Canvas中定义了Left,我们可以在任何控件对象中SetValue(Canvas.Left,v)。凡是可以嵌在Canvas中的控件都可以通过这种方式来设置Left;而Grid也有LeftProperty,同样,凡是可以嵌在Grid中的控件都可以SetValue(Grid.Left,v)。仔细想想,不难发现,在任何一个控件对象中SetValue(Grid.Left,v),最终都会调用Grid类中的一段逻辑。你要是自己定义一个容器控件,比如MyPanel,你在这个类中加一个LeftProperty,然后实现一个设置子控件Left的逻辑,那么所有子控件都可以SetValue(MyPanel.Left,v)了。(关于DependencyProperty以后再说)
  用DependencyProperty定义控件属性的缺点就是不方便,如果是GetValue还要将返回值强制转换。即使是Left,Right这样的常用属性,也要通过SetValue与GetValue方式,很是麻烦。相信下一版本的SL会封闭友好的属性接口。当然这仅仅是为了一个方便而已。


      如果大家发现有地方说的不对,还请指正。

posted @ 2008-04-22 16:22 snowwolflibo 阅读(1588) | 评论 (25)编辑