2006年7月31日星期一

在Microsoft DotNET上進行NNTP Protocol 開發心得

自幾年前,使用VB6開始一直都有寫過下NNTP Newsgroup Access既o野,一直都未有完成品,因為原因實在太多,效能,亂碼,Bug,等等問題都影響到我進展.上左DotNet後,使過很多NNTP既Library,如Smilla .NET Communication Library,雖然沒有亂碼問題,但效能上實在太差.其次那些較出名的IP*Work , Indy Socket等等,雖然效能可接受,但由於始終都是別人出品,要深層次去控制NNTP Protocol 是很難的. 近日的起心干再次研究....得到台灣Microsoft MVP的幫助,有了進展.

在DotNET上,要寫和Server交流的,都是要使用System.Net.Socket低下的Member.
其中TCPCleint是必須的. 除了要對Socket有了解,亦需要了解System.Text.Encoding的使用方法. 因為和外國不同的是,我們是中文字,需要進行轉碼(下文有解說) ,而外國都是英文,故普遍不用轉行轉碼. 而且當然要了解一下RFC977
這份文件.因為從RFC977,我們可以知道NNTP的Command,Response,以及State Code等等有用資料.因為在網上,即使你用Google Search,要找到DotNET上的NNTP資源實在少得可憐.
故以下是我個人小小心得,希望幫到有需要的人,當然有錯請更正^^

1. NNTP Server 接收的資料都是Bytes,而不是String.
當我們由NNTP Server接收到資料時,其實都是以ASCII編碼的Bytes形態.要顯示的話,需要使用ASCIIEncoding.GetBytes方式去取得
Bytes,並轉至DotNET預設的Unicode 和String.如果不轉的話,就是出現"????" 的問號出現了.

2. 傳送資料給NNTP Server其實也是Bytes
一般我們都會使用TCPClient下的GetStream以Read和Write方法去讀寫,就如第一個Point,在GetStream.Write時,都需要把NNTP Command進行String to Bytes的處理才送出.而部份人會使用System.IO下的StreamWriter去送出資料,可能會問,為什麼StreamWriter不用轉Bytes,其實因為StreamWriter在你送出前,已經自動轉成Bytes,所以至可以直接傳送.

3.什麼是MIME ? 什麼是8Bit Encoding ,什麼是Base64 ?
NNTP文章都一定有Mail Header,而Mail Header中都有MIME資訊, MIME含有Subject , Content-Type 和Content-Transfer-Encoding,例如:
Subject: Word =?Big5?B?VkJBpc5XZWJCcm93c2VysN3DRA==?=
Content-Type: text/plain; charset=Big5
Content-Transfer-Encoding: 8bit
Subject不用多說,是標題
Content-Type是信件型式和編碼
Content-Transfer-Encoding則是傳送編碼
明顯地我們看到Subject是未能正確顯示的,就是因為使用8Bit Encoding關係.
8Bit Encode顯示格式為:
=?encode?c?string?=
=? ?= 為起始和結束
encode 為語系編碼
c 為字串編碼方式,b 為 base64 、q 為 Quoted-printable Code.
"VkJBpc5XZWJCcm93c2VysN3DRA"
就是Base64的方式顯示了。
要轉回正常字串,先依字串編碼轉為ByteArray,再使用 .Net 的 Convert.FromBase64String 依語系轉回來即可。

4.如何處回覆的郵件至原文?
若以 Re: 起始的回覆郵件,都會有References的項目 ,一般顯示為 : <a href="mailto:44cc1cd0$1@news.3home.net">44cc1cd0$1@news.3home.net</a> , 冒號後的,就是原文Message-ID,在NNTP Server中的唯一的.故自然可以依據References去連結原文.

2006年7月12日星期三

Flash與ASP.NET共同作業與數據交流心得

Best practices of Flash工作上,近個多月每天都是處理Flash與ASP.NET的事,技術上很易,但出現的未預期錯誤,比想像中多.在Google上找到的,都是教人怎樣去接收發送數據. 所以這篇文重點不會重於技術上,反之會是技巧上.和大家分享一下,從我過去個多月每天都在100%根性上工作所啟發的心得.Flash雖然可以做到很多很酷的動畫,和網頁程式,如最常見的留言板,討論區等...但直到Flash 8,官方還未有任何Provider供Flash做Database存取,而即使MySQL,Oracle都沒有Connector給Flash,當然我知道有Third Party的Socket Component,可以令到Flash得到該功能,但是價錢不便宜,而且效能未明...故依然需要ASP/JSP/PHP做Backend處理....

大家先可看看Intel Software Network中的Flash and .NET Integration Using ASP.NET
在兩者數據交流上,大可以有三種較容易的,都是以Flash的SendAndLoad方式送出:
1. 把數值放在網址上 (如Data.aspx?Name=Ming&Age=24)
但這方法只適合少量數值,如大量數據的話,更是怪怪的,例如我要傳送一段留言,達三百多字,放在網址上..你有看過嗎? 我沒試過,亦保留會出現overflow的可能性. 當然asp一方很方便地以Request.QueryString的方法就可以得數值是不錯的.

2. 把數值以Array方式放在網址上 (如Data.aspx?Value=1|2|3|4|5)
這是一個比起 (1)較折衷的方法,因為我們可以去掉數值前的Item Name,但會苦了asp的一方,因為asp方面要把整個Array,以Split 方式去分割,並取其Index,而且亦因為沒有Item Name,要記著那個Index是代表那個數值是很痛苦的.
example:
Dim StrData as String = Trim(Request.QueryString("Value")
Dim AryData as Array = Split(StrData,"|")
textbox1.text = AryData(1)
textbox2.text = AryData(2)
.....一直下去....

3.以XML中轉檔案方式.
這是一個不錯的選擇,Flash以XML檔案把數值放在Element中,ASP.NET方面亦容易使用XmlTextReader去取數值. 但從Programming上說,由Flash去產生XML檔亦需要時間,而且如果大量使用者的話,伺服器有一定的影響.

三者都有優缺點,要使用那個,就要看情況.
了解過Flash如何把數據送出後,再看看ASP.NET要注意的地方
1.進行QueryString時,視乎情況,使用Trim把空白除去.
有時可能Flash人員沒有留意這個時,就可能會出現很多誤會的情況.即使使用者沒有故意輸入空白,但亦不排除Flash在定義Variable時大意.Teamwork共中就是互相補漏洞吧...

2. response.write前,加上一句Response.Buffer = True
這是ASP時代很重要的,因為我們都知道ASP和ASP.NET不同的是,ASP.NET是有Precompliation的,故所以效能高於ASP,而處理流程是伺服器執行完成程式後,把結果顯示在瀏覽器上,並不是IE去執行ASP,所以我們把IIS要輸出的資料先寫到緩衝區,是保險的一環.在ASP.NET上,很多人都認為不是必須的,但ASP人員是有責任確保Flash能接收完整數據的.

3.事前先決定存取XML中的那個項目
一個XML中可以有很多Parent和Nodes,而Nodes中,亦分Element , attributes等等,Flash可以有選擇性把數值寫在那裡, 在工作前,要確認Flash把數值是寫在那一部份,像我的工作上的Flash程式員,把數值寫在attributes,但我卻把Function寫了讀Element就真是花了無謂時間.

4. 敬請Flash人員建立標準XML
同樣是重要的,直接影響ASP.NET一方,有些人往往把XML寫到一團槽,建立的是XML檔案,同樣有Tags,Parent,Nodes...但有始卻沒有終,卻往往忘記關閉Parent或其他.導致ASP.NET不能正確辨認.

5.盡可能讓Flash的Action Script以Include方式去執行
Flash一方可以直接在Notepad打開*.VB檔,相信你都希望可以直接打開*.AS吧,不用動輒都要開Flash軟件.

6.Flash應建立一個Debug Handler
假如你不修改Web.config中CUSTOM ERROR MESSAGES的話,當問題出現在ASPX上,都能在瀏覽器出現Debug訊息,或者一般程式人員都慣常使用Error Handler或Try..Catch方式.但Flash不同的是,遇到錯誤,往往只會停在Flash Player上,並不會主動做什麼.更不會傳回任何東西回客戶端.最後只會令ASPX人員呆坐....

不過最後我依然是覺得,有些網頁程式,如討論區,都是交回ASP.NET全權負責吧,我個人並不主張網頁全Flash化,顯然濫用只會更像大陸網頁 (一個網頁有十多條Flash Banner....)
暫時想到的只有這些,是我小小的心得,希望大家在萬事俱備下,可以寫得更得心應手.