[C#]自己动手写个ORM实现(4) 关于反射DataRow数据记录到实体性能的优化

mikel阅读(742)

总所周知,反射对于运行时确定对象类型十分方便,但是它最大的不足就是效率低下,比直接调用的效率慢了一百倍有余。

在3.5以前有codeDom或借助Emit直接编写IL来优化其效率,但是使用不便,借助3.5新增的Expression,让我们有了一种既简洁,在速度上又较反射有很大的提高。 示例如下


 1 public static T GetEntityByDataRowSlow<T>(this DataRow data) where T : new()
 2         {
 3             T t = new T();
 4             PropertyInfo[] properties = typeof(T).GetProperties();
 5 
 6             foreach (PropertyInfo p in properties)
 7             {
 8                 object value = data[p.Name] == DBNull.Value ? null : data[p.Name];
 9                 p.SetValue(t, value, null); 
10             }
11             return t;
12         }

 

如上,整段代码慢就慢在p.SetValue(t,value,null)这段上。 也有可能有人会说 typeof(T).GetProperties()获取所有属性应该缓存,但实际测试结果看下来影响并不大,效率相差无几。

接下来,主角登场了

 

 1 static Func<T, MethodInfo, objectobject> GetSetDelegate<T>(MethodInfo m,Type type)
 2         {
 3            
 4             var param_obj = Expression.Parameter(typeof(T), "obj");
 5             var param_val = Expression.Parameter(typeof(object), "val");
 6             var param_m = Expression.Parameter(typeof(MethodInfo), "m");
 7             var body_val = Expression.Convert(param_val, type);
 8             var body = Expression.Call(param_obj, m, body_val);
 9             Action<T, MethodInfo, object> set = Expression.Lambda<Action<T, MethodInfo, object>>(body, param_obj, param_m, param_val).Compile();
10             return (instance, method, v) =>
11             {
12                 set(instance, method, v);
13                 return null;
14             };
15         }

 

1 static void FastSetValue<T>(this PropertyInfo property,T t, object value)
2         {
3             MethodInfo m = property.GetSetMethod();
4             GetSetDelegate<T>(m,property.PropertyType)(t, m, value);
5         }

 

关于Expression和lambda的介绍可参看园里大牛赵哥的文章  方法的直接调用,反射调用与……Lambda表达式调用

经过改良的调用方法

 

 

public static T FastGetEntityByDataRow<T>(this DataRow data) where T : new()
        {
            T t 
= new T();
            PropertyInfo[] properties 
= GetProperties(typeof(T));
            
            
foreach (PropertyInfo p in properties)
            {                    
                
object value = data[p.Name] == DBNull.Value ? null : data[p.Name];
                p.FastSetValue
<T>(t, value);
            }
            
return t; 
        }

 

经过测试下来  如果直接是Entity.Property = "somevalue"设置属性的速度比值是1的话,反射的速度比值是100多,而经过改良的上述方法比值在2-3之间。

尽管这样,常见Web应用的主要瓶颈还是在结构的设计,数据库的读取,上面的方法对于整个程序框架的影响也只是积跬步,单用这个地方用了也几乎白用,不用白不用。谨记录一下。

[C#]在C#中实现Socket端口复用

mikel阅读(800)

一、什么是端口复用:

  因为在winsock的实现中,对于服务器的绑定是可以多重绑定的,在确定多重绑定使用谁的时候,根据一条原则是谁的指定最明确则将包递交给谁,而且没有权限之分。这种多重绑定便称之为端口复用。

二、我们如何实现Socket端口复用:

  其实我们要实现端口复用很简单,我们只要使用SetSocketOption函数设置Socket选项就可以了。MSDN是这样解释的:
Socket 选项确定当前 Socket 的行为。对于具有 Boolean 数据类型的选项,指定非零值可启用该选项,指定零值可禁用该选项。对于具有整数数据类型的选项,指定适当的值。Socket 选项按照协议支持程度来分组。

我们来看看这个函数是怎么用的:

public void SetSocketOption (
    SocketOptionLevel optionLevel,
    SocketOptionName optionName,
    
int optionValue
)

 

参数
optionLevel
SocketOptionLevel 值之一。
optionName
SocketOptionName 值之一。
optionValue
该选项的值。

以上参数大家可以去看看MSDN。我这里就不多讲了。

在这里我们optionLevel 参数传SocketOptionLevel.Socket;optionName参数传 SocketOptionName.ReuseAddress;optionValue参传一个非零值,我传的是True,如果要禁用的话,就传 False。

如:

socket2.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

具体我们看看下面的代码:

我们首先建立第一个Socket:

        Socket socket1;
        IPEndPoint localEP 
= new IPEndPoint(IPAddress.Any, 20000);
        socket1 
= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        socket1.Bind(localEP);

再建立第二个Socket:

        Socket socket2
        IPEndPoint localEP 
= new IPEndPoint(IPAddress.Any, 20000);
        socket2
= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        socket2.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 
true);
       
//请注意这一句。ReuseAddress选项设置为True将允许将套接字绑定到已在使用中的地址。 
        socket2.Bind(localEP);

这样Socket1和Socket2便绑定在同一个端口上了。

例程源代码我上传到我的资源里面大家可以到http://files.cnblogs.com/wzd24/28135640620.rar去下载。

[C#]利用委托实现充血模式的实体类

mikel阅读(923)

最近一直在想实体类应不应该具有操作,还是如以往的一样是缺血模式的实体类呢,目前KiWing框架用的是缺血模式的实体类(缺血实体类指那些只有属性而没有方法的实体类),于是将现有的实体类进行了改写,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KiWing.CustomAttribute;
using KiWing.Helper.Attribute;
namespace KiWing.Test
{
    class Program
    {
        [Table("Table1","Identifier","table1Insert","table1update","table1delete","table1select")]
        public class Test
        {
            /// <summary>
            /// 委托保存方法列表
            /// </summary>
            private SaveMethod saveList;
           
            public int Identifier { get; set; }
            public string TestName { get; set; }
            /// <summary>
            /// 委托保存方法
            /// </summary>
            /// <param name="test"></param>
            /// <returns></returns>
            public delegate int SaveMethod(Test test);
            /// <summary>
            /// 注册保存委托方法
            /// </summary>
            /// <param name="method"></param>
            public void AddSaveMethod(SaveMethod method)
            {
                saveList += method;
            }
            /// <summary>
            /// 删除已经注册的委托方法
            /// </summary>
            /// <param name="method"></param>
            public void RemoveSaveMethod(SaveMethod method)
            {
                saveList -= method;
            }
         
            /// <summary>
            /// 保存方法
            /// </summary>
            /// <returns></returns>
            public int Save()
            {
                if (saveList != null)
                   return saveList(this);
                return 1;
            }
        }
        public class Area
        {
           
        }
        /// <summary>
        /// 业务处理类
        /// </summary>
        public class Business
        {
            public int Save<T>(T obj) where T : class
            {
                Console.Write("Business Save {0}!",typeof(T).Name);
                return 1;
            }
       
        }
        static void Main(string[] args)
        {
            //实例化实体类
            Test test = new Test();
            //属性赋值
            test.Identifier = 1;
            test.TestName="Test";
            //创建业务逻辑对象
            Business business=new Business();
            //注册委托方法
            test.AddSaveMethod(business.Save<Test>);
            //保存数据
            test.Save();
            Console.Read();
          
           
        }
    }
}

[图书]AIR Bible (download)

mikel阅读(941)

Download AIR Bible
下载 AIR 圣经
RIAbook Rank:★★★★

简介 Book Description:
Adobe Integrated Runtime, or AIR, enables developers to create desktop applications using HTML,JavaScript, and ActionScript. These applications are able to run on Windows, Mac OS X, and Linux systems, meaning that Web developers will be able to use familiar languages and tools to easily create desktop software.
A Web application can look the same to every user, on any computer, because the same code is being executed to create the interface. The browser application itself handles the differences between operating systems, which allows code to execute in the same way on a wide variety of machines. A desktop application, on the other hand, starts up quickly because it is run directly from the user’s computer, accesses data quickly because it can store data locally, does not require an Internet connection to run, and is not constrained by the browser window.
Consider the current market of e-mail applications. If you use a Web application for your e-mail,you will be able to access the interface from any computer, and possibly even some mobile devices.
These applications have become very popular as a result, but there are still drawbacks to using a Web application over a desktop application. For example, if you want to find an e-mail you received last week or last month, you often need to page through old messages to find the right place in a Web application. This is a necessity because the data is stored remotely, so the amount of data passed to the browser must be constrained. In a desktop application, messages can be stored locally, and you can easily scroll down to find an older message.
Clearly there are uses for both Web applications and desktop applications. With AIR, there is now a way to use the same interface in both environments. While there may need to be some differences between a Web implementation and a desktop implementation in order to take full advantage of those environments, there is a lot to be gained from not having to create an entirely new application for each environment. AIR, along with other recent developments that enable Web applications to run on the desktop, blurs the line between Web and desktop applications, and it will raise user expectations on both.
One of the most powerful features of Web development languages is that they are high-level scripting languages designed for developing presentation layers. HTML isn’t able to manage memory or access low-level operating system APIs; it was never intended to do such things. Instead, a browser interprets HTML, and the developers of that browser’s engine focus on those things. This allows developers of the higher-level language to focus their efforts on the user experience and the business logic of an application.
In the world of desktop applications, C, C++, Cocoa, Java, and .NET are considered high-level languages.
There is no question that scripting languages like ActionScript and JavaScript are less powerful than these traditional desktop languages. At the same time, Web-scripting languages are also much more focused on user experience and allow for much quicker development. AIR opens up the door to this world and allows the Web development community to prove that user experience is the key to a great application.
Put simply, this is the direction that application development is heading. Users and businesses should not have to wait for developers of lower-level programming languages to reinvent the wheel for every application when the same application could be developed far more quickly using a scripting language interpreted by a low-level framework. Add to that the fact that these same scripting languages can be interpreted by Web browsers and mobile devices, and it’s clear that this is going to create a real shift in the world of application development. AIR is the future of application development, and this is the book to get you on your feet.
目录 Summary of Contents
Part I: Introduction to AIR
Chapter 1: Clearing the AIR
Chapter 2: Setting Up Your Development Environment
Chapter 3: Building Your First AIR Application
Part II: Programming for AIR Essentials
Chapter 4: Crash Course in AIR Programming
Chapter 5: Development Essentials
Chapter 6: Debugging and Profiling
Part III: AIR API
Chapter 7: Communicating with the Local Machine
Chapter 8: Using the Filesystem
Chapter 9: Using the Clipboard
Chapter 10: Dragging and Dropping
Chapter 11: SQLite Databases
Chapter 12: Using Native Operating System Windows
Chapter 13: HTML Content
Part IV: Building an Application
Chapter 14: Preparing to Build a Large-Scale Application
Chapter 15: Building a Reusable Config Class
Chapter 16: Application Design Best Practices
Chapter 17: SDK Development
Chapter 18: Sample Application: LogReader
Chapter 19: Polishing a Finished Application
Part V: Testing and Deploying
Chapter 20: Deployment Workflow
Chapter 21: Leveraging Ant to Automate the Build Process
Chapter 22: Installation and Distribution
Index
关于作者 About the Author
Benjamin Gorton has been developing software for the desktop and the Web for over 10 years. For the
past seven years, he has been working in Flash and ActionScript, doing projects for such companies as
Disney, MTV, Neopets, and Sandisk. He currently resides in Los Angeles, where he works as a Senior
Software Developer for Schematic.
Ryan Taylor is an award-winning artist and programmer specializing in object-oriented architecture,
CGI mathematics/programming, as well as both static and motion design. Ryan, 25, has already landed
his name in the credits of the #1 and #5 all-time best selling video game titles, written for multiple
books, and established himself as an all-around leader in the digital arts community. Currently, Ryan
serves as a senior developer on the Multimedia Platforms Group at Schematic. He also works as an independent
contractor, offering his expertise to top companies and agencies all over the world.
Jeff Yamada lives with his wife AmyLynn and son Jackson in Salt Lake City, Utah, where he is currently
a Senior Interactive Developer at the award-winning RED Interactive Agency. Jeff specializes in the
architecture and development of immersive branded Flash experiences, rich Internet applications, and of
course, AIR applications. As both a designer and developer, Jeff has spent the last ten years freelancing,
consulting, and working for the University of Washington, Microsoft, Avenue A | Razorfish, Schematic,
and Nintendo. Jeff contributes to the open-source community and shares his thoughts and ideas with
the world at http://blog.jeffyamada.com.
http download
From rapidshare : AIR Bible

[Json]Json初探

mikel阅读(825)

JSON初探

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition – December 1999的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。

JSON建构于两种结构:

  • “名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。
  • 值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。

这些都是常见的数据结构。事实上大部分现代计算机语言都以某种形式支持它们。这使得一种数据格式在同样基于这些结构的编程语言之间交换成为可能。

JSON具有以下这些形式:

对象是一个无序的“‘名称/值’对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。

{"UserID":11, "Name":"Truly", "Email":"zhuleipro◎hotmail.com"};

 
数组是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间使用“,”(逗号)分隔。 
[
{"UserID":11, "Name":{"FirstName":"Truly","LastName":"Zhu"}, "Email":"zhuleipro◎hotmail.com"},
{"UserID":12, "Name":{"FirstName":"Jeffrey","LastName":"Richter"}, "Email":"xxx◎xxx.com"},
{"UserID":13, "Name":{"FirstName":"Scott","LastName":"Gu"}, "Email":"xxx2◎xxx2.com"}
]

值(value)可以是双引号括起来的字符串(string)、数值(number)、truefalsenull、对象(object)或者数组(array)。这些结构可以嵌套。

{UserID:001,UserName:"Majie",IsAdmin:true,Rights:{IsAdd:true,IsDelete:false,IsEdit:true},fn:null}

 

字符串(string)是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。

字符串(string)与C或者Java的字符串非常相似。

数值(number)也与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。

 
  • 对象是属性、值对的集合。一个对象的开始于“{”,结束于“}”。每一个属性名和值间用“:”提示,属性间用“,”分隔。
  • 数组是有顺序的值的集合。一个数组开始于"[",结束于"]",值之间用","分隔。
  • 值可以是引号里的字符串、数字、true、false、null,也可以是对象或数组。这些结构都能嵌套。
  • 字符串和数字的定义和C或Java基本一致。
  • [Google]Google Web Toolkit(GWT) v1.5.3 - Google We

    mikel阅读(843)

    如今,编写网络应用程序是一个单调乏味且易于出错的过程。开发人员可能要花费 90% 的时间来处理浏览器行话。此外,构建、重复使用以及维护大量 JavaScript 代码库和 AJAX 组件可能困难且不可靠。Google Web 工具包 (GWT) 通过允许开发人员用 Java 编程语言快速构建和维护复杂但高性能的 JavaScript 前端应用程序来减轻该负担。

    Google Web 工具包工作原理
    有了 Google Web 工具包 (GWT),可以使用 Java 编程语言编写 AJAX 前端,然后 GWT 会交叉编译到优化的 JavaScript 中,而 JavaScript 可以自动在所有主要浏览器上运行。在开发过程中,您可以用 JavaScript 按习惯的相同“编辑 – 刷新 – 查看”循环快速反复,还有另一个好处就是能够调试和逐行单步调试 Java 代码。准备好进行部署后,GWT 会将 Java 源代码编译到优化且独立的 JavaScript 文件中。使用 Google Web 工具包可以轻松地为现有网页或整个应用程序构建一个 Widget。
    使用 Java 语言编写 AJAX 应用程序,然后编译为优化的 JavaScript
    与仅在文本级别运行的 JavaScript Minifier 不同,GWT 编译器会在整个 GWT 数据库中执行综合性静态分析和优化,通常生成的 JavaScript 加载和执行均比等效手写的 JavaScript 更快。例如,GWT 编译器可以安全地消除无用代码 — 极大的减少不使用的类别、方法、字段甚至方法参数 — 以确保您编译的脚本尽可能最小。另一个示例:GWT 编译器选择性地内联方法,消除方法调用的性能开销。
    交叉编译提供了开发所需的可维护的提取和模块性,而不会导致运行时性能损失。
    开发工作流程
    编辑 Java 代码,然后立即查看更改而无需重新编译
    在开发过程中,使用 GWT 的托管模式浏览器可以立即查看代码更改。无需汇编译为 JavaScript 或部署到服务器。只需进行更改,然后在托管模式浏览器中单击“刷新”。
    使用 Java 调试器单步调试当前 AJAX 代码
    在生产过程中,可以将代码编译为纯 JavaScript,但是在开发阶段,代码将在 Java 虚拟机作为字节码运行。这意味着,当代码执行处理鼠标事件等操作时,将获得功能完整的 Java 调试。Java 调试器可以执行的任何操作也应用于 GWT 代码,所以也可以执行断点和单步调试等自然操作。
    编译和部署优化的、跨浏览器的 JavaScript
    准备好进行部署后,GWT 会将 Java 代码编译成独立的纯 JavaScript 文件,任何网络服务器都支持该文件。此外,GWT 应用程序可自动支持 IE、Firefox、Mozilla、Safari 和 Opera,而无需在代码中进行浏览器检测或特殊封装。编写相同的代码后,GWT 会根据每个用户的特殊浏览器将其转换为最有效的 JavaScript。
    功能
    通过非常简单的 RPC 与服务器通信
    GWT 支持一组开放的传输协议,例如 JSON 和 XML,但 GWT RPC 使所有 Java 通信都特别轻松且有效。类似于传统 Java RMI,只需创建一个用于指定您要调用的远程方法的接口。从浏览器调用远程方法时,GWT RPC 将自动串行化参数,并调用服务器上的适当方法,然后反串行化客户端代码的返回值。GWT RPC 也将非常成熟,其可以处理多态类层次结构、对象图循环,甚至可以跨网抛出异常。
    根据用户个人资料优化 JavaScript 脚本下载
    延时绑定是 GWT 的一种功能,可以生成许多版本的编译代码,而在运行时自引导期间仅其中一个版本需要由特殊客户端载入。每个版本均以浏览器为基础生成,并带有应用程序定义 或使用的任何其他轴。例如,如果要使用 GWT 的国际化模块来国际化应用程序,GWT 编译器可能会根据每个浏览器环境生成各个版本的应用程序,例如“英文版 Firefox”、“法文版 Firefox”、“英文版 Internet Explorer”等,因此,部署的 JavaScript 代码非常紧凑并且下载比在 JavaScript 中编码然后声明更快。
    跨项目重复使用 UI 组件
    通过合成其他 Widget 来创建可重复使用的 Widget,然后轻松地在面板中自动对他们进行布局。GWT 展示应用程序可以提供 GWT 中各种 UI 功能的概述。要在其他项目中重复使用 Widget 吗?只需将其打包以便他人在 JAR 文件中使用。
    使用其他 JavaScript 库和本机 JavaScript 代码
    如果 GWT 的类库不能满足您的需要,则可以使用 JavaScript 本地接口 (JSNI) 在 Java 源代码中加入手写的 JavaScript。使用 GWT 1.5,现在就可以为 GWT JavaScriptObject (JSO) 类创建子类以将 Java“类覆盖”创建到任意 JavaScript 对象上。因此,可以获得将 JS 对象比拟为适当的 Java 类型(例如代码完成、重构、内联)而无需另外占用内存或速度的好处。此功能可以优化使用 JSON 结构。
    轻松支持浏览器的后退按钮和历史记录
    不,AJAX 应用程序无需破坏浏览器的后退按钮。使用 GWT,您可以通过轻松地为浏览器的后退按钮历史记录添加状态,来使您的站点更加有用。
    有效的本地化应用程序
    使用 GWT 功能强大的延时绑定技术来轻松创建有效的国际化应用程序和库。此外,从 1.5 版起,标准 GWT Widget 开始支持双向性。
    使用选择的开发工具提高生产力
    由于 GWT 使用 Java,您可以使用所有喜欢的 Java 开发工具(Eclipse、IntelliJ、JProfiler、JUnit)来进行 AJAX 开发。这使网络开发人员可以控制自动化 Java 重构和代码提示/完成的生产效率。此外,Java 语言的静态类型检查使开发人员可以在编写代码时而非运行时找出一类 JavaScript 错误(输入错误、类型不匹配),在减少错误的同时提高生产率。没有临时变量发现的更多用户。最后,则可以利用基于 Java 的 OO 设计模式和提取,由于编译器优化,模式和提取易于理解和维护而无需用户承担任何运行时性能损失。
    使用 JUnit 测试代码
    GWT 与 JUnit 直接集成,使您可以在调试器和浏览器中进行单元测试,并且您甚至可以对异步 RPC 进行单元测试。
    扩展或投稿 – Google Web 工具包是一种开源软件
    使用 Apache 2.0 许可,可获取所有 GWT 代码。如果您对投稿感兴趣,请访问使 GWT 变得更好。
    Google Web Toolkit (GWT) is an open source Java software development framework that makes writing AJAX applications like Google Maps and Gmail easy for developers who don't speak browser quirks as a second language. Writing dynamic web applications today is a tedious and error-prone process; you spend 90% of your time working around subtle incompatibilities between web browsers and platforms, and JavaScript's lack of modularity makes sharing, testing, and reusing AJAX components difficult and fragile.
    GWT lets you avoid many of these headaches while offering your users the same dynamic, standards-compliant experience. You write your front end in the Java programming language, and the GWT compiler converts your Java classes to browser-compliant JavaScript and HTML.
    Release Notes for 1.5.3
    Fixed Issues
    RPC requests no longer fail on the embedded Android web browser
    Leaf TreeItems now line up with their non-leaf siblings
    Removing the last child node from a TreeItem no longer creates extra margins on the left
    HTTPRequest no longer uses POST instead of GET on some IE installs because of incorrect XHR selection
    Compiler now uses a more reliable check to prevent methods with local variables from being inlined
    getAbsoluteTop()/Left() can no longer return non-integral values
    Time.valueOf() no longer fails to parse "08:00:00" or incorrectly accepts "0xC:0xB:0xA".
    更新:http://code.google.com/intl/zh-CN/webtoolkit/releases/release-notes-1….
    官网:http://code.google.com/webtoolkit
    官方下载:
    Windows:http://google-web-toolkit.googlecode.com/files/gwt-windows-1.5.3.zip
    Mac OS X:http://google-web-toolkit.googlecode.com/files/gwt-windows-1.5.3.zip
    Linux:http://google-web-toolkit.googlecode.com/files/gwt-linux-1.5.3.tar.bz2

    [MVC]调试、部署Oxite 开源系统

    mikel阅读(1171)

    调试、部署Oxite 开源系统
     
    Oxite 是微软近期发布了一个开源CMS或博客平台,关于Oxite 系统的基本介绍,请参考文章 – 微软发布Oxite开源CMS博客平台。
     
    这里,EntLib.com 开源论坛小组一步一步详细介绍如何编译、调试和部署 Oxite 系统。假设你的系统已经有SQL Server 2005 和 Visual Studio 2008。
     
    1. 首先下载并安装 ASP.NET MVC 开发包。
    ASP.NET MVC下载地址:
     
    如果你之前有安装 ASP.NET MVC 的前期版本,则你需要先下载早期的版本。ASP.NET MVC 的安装过程很简单,这里就不具体介绍了。
    关于ASP.NET MVC 的介绍,推荐你阅读如下文章:
    Microsoft ASP.NET MVC Preview 5 及LINQ TO SQL最新版开发示例演示(提供源码下载)
     
    2. 下载 Oxite 开源软件。
    展开压缩文件,通过 Visual Studio 2008 打开Oxite.sln 项目文件。先看看项目文件:
     
     
    接下来,设置 OxiteSite 项目为启动项目(Set as Startup Project)。编译整个Oxite 项目,整个项目编译通过。到现在,一切都很顺利。
     
    但是,当你运行OxiteSite 项目时,Visual Studio 2008 会提示你Deploy Failed-发布失败。仔细看看,这是Oxite.Database 项目产生的。
     
    最简单的解决办法是,右键单击Oxite.Database项目,选择 Unload Project 或者 Remove 菜单项,如下图所示。
     

     
    现在,你再次运行Oxite 项目,发现可以正常运行了,并且显示如下运行界面。
     
     
    Oxite.Database 项目到底有什么用呢?这里,Oxite.Database 项目用来创建Oxite 数据库,由于OxiteSite Web项目采用的是SQL Server Express进行 Oxite 数据库连接。数据库连接字符串Connection String 如下:
     
     <connectionStrings>
        <add name="ApplicationServices" connectionString="Data Source=.\SQLEXPRESS;AttachDBFileName=|DataDirectory|Oxite.Database.mdf;Integrated Security=true;User Instance=true;"/>
     </connectionStrings>
    默认,数据库文件存放在\OxiteSite\App_Data 目录下。所以,上面的Oxite.Database 项目可以直接Unload 或者 Remove。
     
    如果你想通过Oxite.Database 直接在SQL Server 2005 创建一个Oxite 的数据库,你也可以按照如下的步骤,轻松创建Oxite数据库。
    首先,需要修改Oxite.Database 项目的一些设置,如下图所示:
    (1) 设置Default collation 属性为 Chinese_PRC_CI_AS,采用中文字符集。
     
     
    (2) 正确设置Oxite.Database 项目的Target database name 属性为:Oxite。同时,设置Default location for target database files – 默认数据库文件存放位置属性为:c:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\。这一属性根据实际情况,可以设置为其他路径。
    具体设置信息如下图所示:
     
     
    现在,编译、部署Oxite.Database 项目就可以正确通过了。此时,你可以进一步修改OxiteSite 项目中的web.config 配置文件,修改其中的数据库连接字符串 Connection String。如下所示:
     <connectionStrings>
        <addname="ApplicationServices"connectionString="Server=localhost; Database=Oxite;Integrated Security=true;"/>
     </connectionStrings>
     
    现在,重新编译、运行OxiteSite 项目,数据库连接到 SQL Server 2005 中的Oxite 数据库了,而不是先前的SQL Server express 的Oxite.Database.mdf 数据库文件。
     
    本文由http://forum.entlib.com 开源论坛小组提供,欢迎交流、讨论、分享。
     
    相关文章:
    1. 微软发布Oxite开源CMS博客平台
     
    2. Oxite 配置入门文章
     
    3. Microsoft ASP.NET MVC Preview 5 及LINQ TO SQL最新版开发示例演示(提供源码下载)

    [SQL]SQL Server2005 Sp3

    mikel阅读(900)

    Feature Pack for SQL Server 2005 December 2008

    Download the December 2008 Feature Pack for Microsoft SQL Server 2005, a collection of standalone install packages that provide additional value for SQL Server 2005.

    12/15/2008

    Microsoft SQL Server Protocol Documentation

    The Microsoft SQL Server protocol documentation provides technical specifications for Microsoft proprietary protocols that are implemented and used in Microsoft SQL Server 2008.

    12/15/2008

     

    SQL Server 2005 Express Edition with Advanced Services SP3

    Microsoft SQL Server 2005 Express Edition with Advanced Services is a free, easy-to use version of SQL Server Express that includes more features and makes it easier than ever to start developing powerful data-driven applications for web or local desktop development.

    12/15/2008

     

    SQL Server Management Studio Express SP3

    Microsoft SQL Server Management Studio Express (SSMSE) is a free, easy-to-use graphical management tool for managing SQL Server 2005 Express Edition and SQL Server 2005 Express Edition with Advanced Services.

    12/15/2008

    SQL Server 2005 Express Edition Toolkit SP3

    Microsoft SQL Server 2005 Express Edition Toolkit provides additional tools and resources for SQL Server 2005 Express Edition and SQL Server 2005 Express Edition with Advanced Services.

    12/15/2008

     

    SQL Server 2005 Express Edition SP3

    Microsoft SQL Server 2005 Express Edition is a free, easy-to-use, lightweight version of SQL Server 2005. It is fast and easy to learn, allowing you to quickly develop and deploy dynamic data-driven applications.

    12/15/2008

    SQL Server Data Mining Add-ins for Office 2007

    Download SQL Server 2005 Data Mining Add-ins for Office 2007. This package includes two add-ins for Microsoft Office Excel 2007 (Table Analysis Tools and Data Mining Client) and one add-in for Microsoft Office Visio 2007 (Data Mining Templates).

    12/15/2008

    SQL Server Reporting Services Add-in for SharePoint Technologies

    The Microsoft SQL Server 2005 Reporting Services Add-in for Microsoft SharePoint Technologies is a Web download that provides features for running a report server within a larger deployment of Windows SharePoint Services 3.0 or Microsoft Office SharePoint Server 2007.

    [C#]基于socket的聊天室实现原理

    mikel阅读(857)

    基于socket的聊天室,目前还比较少见,国内比较知名的有网易和碧海银沙聊天室。这种聊天室的特点 很明显,不象CGI聊天室那样不管有没有人发言,都会定时刷新。而是当有人发言时,屏幕上才会出现新聊天内容,而且聊天内容是不断向上滚动的,如果浏览器 状态栏在的话,可以看到进度条始终处于下载页面状态。这种聊天室可以容纳许多人而性能不会明显降低,象网易聊天室经常有数百人在一台服务器上聊天。由于这 种方式不同于CGI聊天室由客户端浏览器定时请求聊天内容,而是由聊天服务器软件向客户浏览器主动发送信息。
    Socket聊天室基本原理是,抛开cgi和www服务器,根据html规范,接收到浏览器的请求以后,模仿www服务器的响应,将聊天内容发回浏览器。 在浏览器看来就象浏览一个巨大的页面一样始终处于页面联接状态。实际上就是一个专门的聊天服务器,一个简化了的www服务器。
    这样相比CGI方式来说,Socket聊天室的优点就很明显:
    1. 不需要专门的WWW Server,在聊天服务器里完成必要的工作,避开耗时的CGI过程
    2. 如果使用单进程服务器,就不需要每次产生新进程
    3. 数据交换完全在内存进行,不用读写文件
    4. 不需要定时刷新,减少屏幕的闪烁,减少对服务器的请求次数

    在讨论具体流程之前,我们先来讨论相关的一些技术:

    http请求和应答过程
    http协议是浏览器与www服务器之间通信的标准,作为一个简化了的www服务器,socket聊天服务器应当遵守这个协议。实际上只要实现一小部分就可以了。
    http使用了客户服务器模式,其中浏览器是http客户,浏览某个页面实际上就是打开一个连接,发送一个请求到www服务器,服务器根据所请求的资源发 送应答给浏览器,然后关闭连接。客户和服务器之间的请求和应答有一定的格式要求,只要按照这个格式接收请求发送应答,就可以“欺骗”浏览器,使它以为正在 与www服务器通信。
    请求和应答具有类似的结构,包括:
    · 一个初始行
    · 0个或多个header lines
    · 一个空行
    · 可选的信息
    我们看看一个浏览器发出的请求:
    当我们浏览网页:http://www.somehost.com/path/file.html的时候,浏览器首先打开一个到主机www.somehost.com的80端口的socket,然后发送以下请求:
    GET /path/file.html HTTP/1.0
    From: someuser@somehost.com
    User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 4.0; DigExt)
    [空行]

    第一行GET /path/file.html HTTP/1.0是我们需要处理的核心。由以空格分隔的三部分组成,方法(method):GET,请求资源:/path/file.html,http版本:HTTP/1.0。

    服务器将会通过同一个socket用以下信息回应:
    HTTP/1.0 200 OK
    Date: Fri, 31 Dec 1999 23:59:59 GMT
    Content-Type: text/html
    Content-Length: 1354

    <html>
    <body>
    <h1>Hello world!</h1>
    (其他内容)
    .
    .
    .
    </body>
    </html>
    第一行同样也包括三部分:http版本,状态码,与状态码相关的描述。状态码200表示请求成功。
    发送完应答信息以后,服务器就会关闭socket。
    以上过程可以利用telnet www.somehost.com:80来模拟。

    循环服务器和并发服务器
    循环服务器是一个时刻只能处理一个请求的服务器,多个请求同时到来将会放在请求队列里。
    而并发服务器则是在每个请求到来以后分别产生一个新进程来处理。
    并发服务器由于其算法而具有与生俱来的快速响应优势,而且当某一个用户与服务器通信死锁不会影响其他进程,但由于多个进程之间需要通过进程间通信实现信息交换,而且fork新进程所带来的开销随着用户数量的增加越来越大,因此并发服务器在某些情况下不一定是最佳选择。
    循环服务器虽然表面上会产生时延,但是象聊天室这样的系统实际上处理每个请求的过程非常的短,对客户而言,可以取得与并发服务器一样的效果,而且由于是单 进程服务器,不需要进程间通信,不需要fork新进程,编程简单,系统资源消耗极少。但由于是单进程,某个客户与服务器之间死锁将导致整个系统死锁。

    POST与GET
    提交form信息一般常用的有两种:POST & GET,POST由于长度不受限制,而作为大多数form提交时使用的方法。GET方法通过URL来发送提交信息,由于URL最长只能1024字节,所以 如果发送信息很长的话,不能使用这种方法。由于聊天内容有长度限制,不会很长,而且因为普通浏览页面使用GET方法,因此使用GET方法提交form表 单,可以简化处理过程。

    使用perl模块实现Socket通信
    假定您对socket编程有一定的了解,如果您使用过C语言进行过socket编程,那么理解perl语言socket编程将是一件非常容易的事。如果不熟悉socket,请看本文所附socket参考。
    使用perl编写socket程序可以通过use Socket,也可以通过use IO::Socket。前一种方法接近于C语言,后一种则进行了对象封装,编写维护会容易许多。

    我们在通过单进程循环服务器实现并发服务的时候,基本思路是:允许多个客户打开到服务器的socket 连接,服务器通过一定的方法监测哪些socket有数据到达,并处理该连接。在这个思路中有个关键问题服务器如何触发数据处理?了解C语言socket编 程就会知道有个系统函数select可以完成这一操作,但由于使用了位操作,perl语言处理不是很清晰,但是如果使用了模块IO::Select就会变 得很简单。
    我们看一个来自IO::Select的帮助的例子:
    use IO::Select;
    use IO::Socket;

    $lsn = new IO::Socket::INET(Listen => 1, LocalPort => 8080);
    #创建socket,在端口 8080上监听,相当于使用系统函数
    #socket(),bind(),listen()

    $sel = new IO::Select( $lsn );
    #创建select对象,并把前面创建的socket对象加入

    while(@ready = $sel->can_read) {#处理每个可读的socket
    foreach $fh (@ready) {
    if($fh == $lsn) {
    #如果最初创建的socket可读,说明有新连接
    #建立一个新的socket,加入select
    $new = $lsn->accept;
    $sel->add($new);
    }
    else {
    #如果是其他socket,读取数据,处理数据
    ……
    #处理完成以后,从select中删除socket,然后关闭socket
    $sel->remove($fh);
    $fh->close;
    }
    }
    }
    IO::Socket的基本操作,
    创建socket对象:$socket=new IO::Socket::INET();
    接收客户的连接请求:$new_socket=$socket->accept;
    通过socket发送数据:$socket->send($message);
    从socket接收数据:$socket->recv($buf,LENGTH);
    关闭socket连接:$socket->close;
    判断socket是否出于打开状态:$socket->opened;

    IO::Select的基本操作
    创建select对象:$select=new IO::Select();
    添加socket到select中:$select->add($new_socket);
    从select中删除socket:$select->remove($old_socket);
    从select中查找可读的socket:@readable=$select->can_read;
    找出select中的所有socket:@sockets=$select->handles;

    Daemon实现方法
    实现一个后台进程需要完成一系列的工作,包括
    · 关闭所有的文件描述字
    · 改变当前工作目录
    · 重设文件存取屏蔽码(umask)
    · 在后台执行
    · 脱离进程组
    · 忽略终端I/O信号
    · 脱离控制终端
    这些操作可以利用perl模块来简化:
    use Proc::Daemon;
    Proc::Daemon::Init;


    pipe信号处理
    如果客户关闭了socket以后,服务器继续发送数据,将会产生PIPE Signal,如果不加处理,就会导致服务器意外中断,为避免这一情况的发生,我们必须对它进行处理,一般情况下,只需要简单地忽略这个信号即可。
    $SIG{‘PIPE’}=’IGNORE’;

    意外处理
    在Socket通信过程中很容易出现一些意外情况,如果不加处理直接发送数据,就可能导致程序意外退出。Perl语言中的eval函数可以用于意外处理。例如:
    if (!defined(eval{操作语句;})){
    错误处理;
    }
    这样当eval中的操作语句出现错误,如die的时候,只会中止eval语句,并不会中断主程序。

    用户断线判断和处理
    许多情况下,用户不是通过提交“离开”按钮离开聊天室,这时候就需要判断用户是否断线了。方法是:当用户关闭浏览器,或者点击了浏览器stop按钮,或者跳转到其他网页的时候,相对应的socket将会变成可读状态,而此时读出的数据却是空字符串。
    利用这个原理,只要在某个可读的socket读取数据时,读到的却是空数据,那么我们就可以断定,与这个socket相对应的用户断线了。

    防止用户断线
    如果浏览器在一段时间内没有接到任何数据,那么就会出现超时错误。要避免这一错误,必须在一定间隔内发送一些数据,在我们这个应用系统里,可以发送一些html注释。发送注释的工作可以由在线名单刷新过程顺带完成。

    下面我们来看看具体实现流程:
    聊天服务器实现流程
    · 服务器端
    下图是NS盒图程序流程:


    上图中的“处理用户输入”部分可以细化为下图:

     

    用户数据输入都是通过URL传送,下面是几个url实例,结合后面客户端流程,可以更好地理解系统结构:
    这是一个用户名密码均为’aaa’的聊天用户登录系统,说了一句话“hello”,然后退出所产生的一系列请求,其中密码用系统函数crypt加密过:
    /login?name=aaa&passwd=PjHIIEleipsEE
    /chat?sid=ZUyPHh3TWhENKsICnjOv&passwd=PjHIIEleipsEE
    /talk?sid=ZUyPHh3TWhENKsICnjOv&passwd=PjHIIEleipsEE
    /names?sid=ZUyPHh3TWhENKsICnjOv
    /doTalk?sid=ZUyPHh3TWhENKsICnjOv&passwd=PjHIIEleipsEE&message=hello
    /leave?sid=ZUyPHh3TWhENKsICnjOv&passwd=PjHIIEleipsEE

    以上是服务器程序流程,下面我们从客户端看看具体登录过程。
    我们先看看聊天界面:


    聊天界面由三个frame组成,其中chat帧是聊天内容显示部分;talk帧是用户输入部分,包括聊天内容输入、动作、过滤以及管理功能都在这一帧输入;names是在线名单显示部分,这一部分是定时刷新的。

    让我们从浏览器的角度来看看进入聊天室的过程。
    · 首先浏览器请求页面
    http://host:9148/login?name=NAME&passwd=PWD
    此时产生了一个连接到服务器聊天端口的socket联接,并发送了一行数据:
    GET /login?name=NAME&passwd=PWD HTTP/1.1
    · 服务器生成一个session ID,验证密码以后,发回:
    HTTP/1.1 200 OK
    <其他头信息>
    Content-TYPE: text/html
    <空行>
    <html>
    ……
    <frameset cols="*,170" rows="*" border="1" framespacing="1">
    <frameset rows="*,100,0" cols="*" border="0" framespacing="0">
    <frame src="/chat?sid=$sid&passwd=$encrypt_pass" name="u" frameborder="NO" noresize>
    <frame src="/talk?sid=$sid&passwd=$encrypt_pass" name="d" frameborder="NO" noresize>
    </frameset>
    <frame src="/names?sid=$sid" name="r" noresize>
    </frameset>
    ……
    </html>
    然后服务器关闭socket联接。

    · 浏览器收到以上html文件后,将会依次打开三个联接(其中的$sid和$encrypt_pass是变量):
    /chat?sid=$sid&passwd=$encrypt_pass /talk?sid=$sid&passwd=$encrypt_pass
    /names?sid=$sid
    这三个联接中的第一个联接chat在整个聊天过程中都是保持联接的,这样从浏览器角度来看,就是一个始终下载不完的大页面,显示效果上就是聊天内容不是靠 刷新来更新,而是不断地向上滚动。通过察看html代码可以看到,只有<html><body>,然后就是不断增加的聊天内容, 没有</body></html>。
    另外两个联接在页面发送完毕以后,socket就关闭了。
    这样一次登录聊天室实际上有四次socket联接,但登录完成以后,只有chat帧的socket是保持联接的,用于接收来自服务器的聊天信息,这是socket聊天室的关键所在。
    在服务器端储存了所有参加聊天的客户的chat socket,当有人发言时,服务器就向所有chat socket发送聊天内容。
    Talk与names帧的html实际上和普通的form是一样的。

    · 在用户登录以后,服务器端保存了一张包括用户信息的表格。
    在perl实现中,我们使用哈希结构储存信息,以session ID作为key索引。这样的存储结构便于存取数据,回收空间。每个客户信息是一个数组:
    [socket,name,passwd,privilige,filter,login_time,color]
    socket:储存chat帧socket联接
    name:用户名
    passwd:密码
    privilige:权限
    filter:某个用户的过滤列表的引用(reference)
    login_time:记录登录时间,以便以后清除一些超时联接
    color:用户聊天颜色
    以上用户数据大部分是在login阶段,用户通过密码验证以后填入的。只有chat socket要等到chat帧显示以后才得到。如果超过一定时间,socket还是没有填入,说明浏览器取得主框架以后连接中断了,这时候就需要删除该用户数据。

    以上是聊天室核心部分,其他部分,如用户注册、改密码等可以沿用CGI聊天室代码。

    需要改进的地方
    目前提供了聊天、悄悄话、动作这些基本聊天功能以及过滤用户名单这样的附加功能。管理功能完成了踢人、查IP、任命室主。今后需要改进的地方有:
    稳定性:目前聊天室还没有经过大用户量测试,稳定性还不能充分保证。由于是单进程循环服务器,某个用户通信死锁将导致所有人死锁。如果采用并发多进程服务器,可以使稳定性得到提高。但这样的系统对服务器资源消耗也会大许多。
    功能:自建聊天室等功能还没有完成,这些外围功能在稳定性有保证以后就可以比较容易地加入。

    [参考内容]
    1. 本文所述的聊天室的最初结构来自于Entropy Chat 2.0(http://missinglink.darkorb.net/pub/entropychat/),如果没有它的启示,完成这一系统会有许多 困难,非常感谢他们的努力工作,愿意共同完善这个程序的朋友们,可以到http://tucows.qz.fj.cn/chat下载源代码。

    2. http的基本交互过程请参考
    HTTP Made Really Easy(http://www.jmarshall.com/easy/http/),RFC1945:Hypertext Transfer Protocol — HTTP/1.0

    3. 本文所提到的perl模块,都可以在http://tucows.qz.fj.cn找到,请使用页面上方的搜索功能搜索。
    IO::Socket和IO::Select是perl标准模块,也可以通过安装IO-1.20.tar.gz得到。
    Proc:Daemon需要另外安装,模块为Proc-Daemon-0.02.tar.gz
    上述模块版本号可能有所不同,搜索时只要输部分关键字如:”Daemon”即可找到。

    4. 为加快开发过程,程序的界面部分参考了网易聊天室(http://chat.163.net/),程序的很多想法也来自于他们的工作。

    5. 《How to Write a Chat Server》可以作为一个很好的参考
    http://hotwired.lycos.com/webmonkey/97/18/index2a.html

    6. 需要测试聊天室功能可以到http://tucows.qz.fj.cn/chat;
    7. socket编程参考
    · Unix Socket FAQ(http://www.ntua.gr/sock-faq/)
    · Beejs Guide to Network Programming
    (http://www.ecst.csuchico.edu/~beej/guide/net/

    [Python]IronPython 2.0 发布了

    mikel阅读(806)

           DLR团队终于发布了 IronPython 2.0 ,IronPython 2.0完全基于Dynamic Language Runtime (DLR). DLR允许多个动态语言在系统类型层面实现互操作。这个版本修复大概500多个bug,有453个来自codeplex社区的反馈。热烈祝贺开发团队发布 了这一个重大的里程碑版本。可以到codeplex上去下载,下面是一些重要的链接:

    下面是IronPython 2.0一些说明: