About Me

我的相片
台北市, Taiwan
我是方選,
方白科技(finebind tech.)共同創辦人,
臺大資管所畢,
希望能幫助更多的人!

FB: http://fb.com/function1122
LINE: http://bit.ly/1foeZft (手機開啟點擊網址自動加入)

最新15則讀者回應

最新文章

FUNction's 上課筆記

Label Cloud

Blog Archive

FeedBurner

追蹤者

顯示具有 C# 標籤的文章。 顯示所有文章
顯示具有 C# 標籤的文章。 顯示所有文章

UCMA Simple Bot Part 3 (如何解決8分鐘機器人不回應的問題)

由 FUNction 於 2008年6月19日 下午3:12 發表
English Title: [HOW TO] Solve the UCMA Bot can't receive invite or message after 8 mins.

之前Chming 在我Blog 問我之後,過不久Vincent 在UCMA 論壇問了相同的問題(國人推斷兩人應該是同一人),可惜到最後都沒有人會。沒關係,我們來看看國人如何讓機器人在20 分鐘之後仍然會理國人吧。

這篇的步驟是教大家從IDKStudioServer 改裝成會持續收到訊息的機器人,希望對UCMA 的開發者會有幫助。我先把重點放在如何解決,然後再稍微討論一下,我對為什麼可以成功的見解。

開始修改程式碼:
首先,先開啟有Connection Manager 的程式碼(這邊僅更改TLS 部分,TCP 部分相信聰明的你可以舉一反三):
  1. 先將private 變數_connectionManager 的型別改為"RealTimeConnectionManager"
  2. 在RegisterEndpoint 的一開頭加入以下語法
    IPAddress localIpAddress = Dns.GetHostAddresses(Dns.GetHostName())[0];
  3. 跳到TLS 的區塊(如果是TLS 則執行...)裡面增加一個變數
    RealTimeServerTlsConnectionManager serverTlsConnectionManager;
  4. 刪除
    _connectionManager = (RealTimeServerConnectionManager)new RealTimeServerTlsConnectionManager(憑證名稱, 憑證序號);"

    換成
    serverTlsConnectionManager = new RealTimeServerTlsConnectionManager(憑證名稱, 憑證序號);"
  5. 在catch 外面加入以下程式碼:

    //Turn on MTLS so that InteractiveBot can be trusted by OCS.
    serverTlsConnectionManager.NeedMutualTls = true;

    _connectionManager = (RealTimeConnectionManager)serverTlsConnectionManager;

    if (!serverTlsConnectionManager.IsListening)
    {
    try
    {
    serverTlsConnectionManager.StartListening(new IPEndPoint(localIpAddress, 0));
    }
    catch (ConnectionFailureException e)
    {
    hrow new InvalidOperationException(e.Message);
    }
    }
  6. 接下來要把RegisterCallback 裡面的
    _connectionManager.StartListening(new IPEndPoint(IPAddress.Loopback, 0));
    刪掉或注掉吧
  7. 打完收工!


我們來看看之前問題出在哪?為什麼機器人不回應了。
我以為問題出在RealTimeServerConnectionManager ,雖然到現在我仍然搞不清楚這麼多種Connection Manager 有什麼特別的目的。總之就是把Connection Manager 換成RealTimeConnectionManager 就ok了。此外,RealTimeConnectionManager 不支援StartListening 方法,但是在轉型之前我們仍然可以用RealTimeServerTlsConnectionManager 取得這個方法。所以在該篇Marc Wetters (reply#3) 有回答到點,問題的確出在Connection Manager ,也許是他一時口誤吧。

順帶一提,這些程式碼其實是跟Interactive Bot 有樣學樣做出來的,因為那時候Chming 提醒了我,Interactive Bot 可以持續回應,為什麼IDK Bot 卻不行...恩,總之以後在開發機器人的時候請大家愛用RealTimeConnectionManager ,不用再跟什麼鬼RealTimeServerConnectionManager 玩了吧!
繼續閱讀全文 UCMA Simple Bot Part 3 (如何解決8分鐘機器人不回應的問題)

C# 檔案附加文字

由 FUNction 於 2008年3月28日 晚上8:54 發表
今天為了Debug ,我要嘗試開啟一個文件,將文字附加在文件尾端。我相信檔案操作是初學者感到困難的一塊,而把文字附加在檔案尾端,這應該可以滿足不少老師的作業。為了不要讓你覺得我是不是太孤單,所以我不講費話,直接進入程式:
filename: Appends.cs
using System;
using System.IO;
class Appends
{
public static void Main(String[] args)
{
//這邊應該是使用"附加"的方式將檔案開啟
using (StreamWriter w = File.AppendText("log.txt"))
{
//使用WriteLine 將文字入之後加上換行符號
w.WriteLine ("Your append text!");
//以我程式語言的經驗,這應該是把文字寫進檔案
w.Flush();
//關閉檔案
w.Close();
}
}
}

參考資料:http://msdn2.microsoft.com/zh-tw/library/3zc0w663(VS.80).aspx

這程式應該可以直接貼上去直接用,雖然我沒test 過,但片段程式碼應該是ok 的,如果有問題也請跟我分享吧!!
繼續閱讀全文 C# 檔案附加文字

UCMA 取得對話對象的名稱

由 FUNction 於 2008年3月27日 下午4:09 發表
在UCMA 的開發裡,如果要取得對話對象的資料,需要用到SignalingSession 的RemoteParticipant 。SignalingSession 就是跟對方講話的session ,RemoteParticipant 是它的一個property 。
這個property 在MSDN 裡面並沒有詳細的介紹(請參見 http://msdn2.microsoft.com/en-us/library/microsoft.rtc.signaling.signalingsession.remoteparticipant.aspx),研究了一下,我在這裡分享幾個比較有趣的property 內容:

  • ContactUri(string): Retern 一串我看不出來是什麼的東西,不像LDAP 路徑,類似於:_sip:administrator@msft.com;opaque=user:epid:TJQrEP0QnFW8hA9PhB94qAAA;gruu;另一個屬性Gruu 也傳回相同的值。
  • EndpointId(string): Return 一個類似於這樣的ID: 1ca51363bd,這應該是對方EndPoint 在OCS 裡註冊的ID。
  • Name(string): Return 對方使用者在OCS 中的顯示名稱,例如: Administrator。
  • Uri(string): Return 對方的sip uri,它的結果會類似這樣"_sip:administrator@msft.com",值得注意的是前面有"_sip:"。
  • UriAtHost(string): 在AD 中,這可以回傳對方使用者的UPN,傳回訊息類似於: administrator@msft.com。

我覺得比較值得注意的是Name 和UriAtHost ,這樣我們在對話中就可以知道對方來者何人了。好啦,老實說我覺得這一點都不有趣。
繼續閱讀全文 UCMA 取得對話對象的名稱

我與ASP.NET 的第一次接觸

由 FUNction 於 2008年1月18日 下午5:49 發表
沒錯...我今天才第一次寫ASP.NET ,所以我要在此鼓勵大家
如果你已經開始寫ASP.NET 的話,你的成就一定超越我了;如果你還沒開始寫,別灰心,我也比你早寫一天而已(而且以後不一定會一直寫)

這個網頁使用者傳給他一個URL 參數,就可以自動讓使用者下載同資料夾裡的檔案(這什麼爛功能Q__Q)
假設網頁名稱叫做:getfile.aspx
在同資料夾裡有檔案叫作: function_wei.doc

使用者在網址列輸入: http://localhost/getfile.aspx?path=function_wei.doc
那支aspx 就會讓使用者下載 function_wei.doc
就這麼簡單Q__Q,這支程式感覺起來很無用,但裡面牽涉兩個重要的aspx 方法:Page_load和 接收URL參數,事不宜遲,我們來看程式碼吧:

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
string tmppath = "";
//這裡就是Page_load 囉,當載入網頁就會執行這裡:P
void Page_load(object sender, EventArgs a)
{
if (Request.QueryString["path"] != null)
{
//在呼叫網頁給的參數path 可以用

//Request.QueryString["path"]取得
tmppath = Request.QueryString["path"];
}
}
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>ASP.NET Part 1</title>
</head>
<body>
<p align="center"><font face="Arial" color="#0000ff" size="5"><strong>The file downloaded.</strong></font></p>
<p align="center">If <i>"<%=tmppath %>"</i> do not auto download, click [<a href="<%=tmppath %>">here</a>]</p>
<iframe style="display:none" src="<%=tmppath%>" />
(其實是很鳥的用一個IFrame 把檔案指定在裡面Q__Q,這裡值得一提的是我們用<%=tmppath %> 就可以輸出C# 的變數,帥吧)
</body>
</html>


我這方面還很弱,請各位高手指正囉 :-)
繼續閱讀全文 我與ASP.NET 的第一次接觸

UCMA Simple Bot (國人自製) Part 1

由 FUNction 於 上午11:09 發表
國人就是我...
自從那個死老外沒有回應我之後
國人仍然不放棄,結合IDKStudioServer 與InteractiveBot 研發出超級輕巧的機器人MOSSAgent
這個機器人目的是打算能與MOSS 溝通(目前沒有實做這個部分,只有機器人對話的功能)
機器人的功能有:
  • 自動接受Communicator 邀請
  • 能回應使用者自Communicator 發出的文字訊息
  • 能接受兩個以上的使用者

機器人的改進有:
  • 重要部分的程式碼採用中文註解!!!
  • 自動抓取Tls憑證(IDKStudioServer無)
  • 能調整上線狀態(IDKStudioServer與InteractiveBot均無)
  • 只要簡單設定機器人就可以使用(依環境更改Settings.xml)

以下截取部分機器人畫面:

從Communicator 用戶端與機器人對話截圖(可以發現機器人對話模式與我很像><)
機器人介面,畫面中可以控制機器人登入,也可檢視機器人收到的訊息


只要編輯Settings.xml 就可以設定機器人
這個地方我們會發現,讓機器人登入不需要設定使用者的密碼,不要懷疑也不要害怕,這是因為我在程式碼建立endpoint 的時候就寫成不需要密碼(因為寫"需要密碼"會有例外Orz)


這是他接收訊息的程式碼,用個很簡單的switch 判斷使用者輸入的字義:P

看了這麼多,如果你是開發者的話應該最有興趣的是下載的連結,我不是一個小氣的人,就放在這兒囉
[download source code]

如果:
  • 你覺得這個程式對你有幫助,請你回復一下讓我知道喔^^(如果都沒回覆我下次就不放source 了Q__Q)
  • 有什麼問題也可以問我,因為這程式我大部分都看得懂(雖然是我寫的:P)
繼續閱讀全文 UCMA Simple Bot (國人自製) Part 1

Wiimote 實現Multi-touch 與3D 的特別報導

由 FUNction 於 2008年1月3日 上午11:45 發表

實現Multi-touch (多重觸控)
以後做簡報想要來點花招可以試試看

實現3D
真是太神了...

其實如果大家有在注意這這方面可能早就知道癮科技有報導過
不過礙於我真的太忙了,沒時間整理
現在偷到一點自己的時間,也沒整理得很好,真是抱歉了
如果你在微軟待過,說不定你會覺得Johnny Lee 跟我們的Peter 有點神似呢

技術人員請注意:
原來Wiimote 是用C#開發的,而且程式碼放在Source Forge上
這是他們的開發主頁 http://sourceforge.net/projects/wiiwhiteboard/
這個連結可以看到程式碼 http://wiiwhiteboard.cvs.sourceforge.net/wiiwhiteboard/source/windowsxp/WiimoteLib/Wiimote.cs?view=markup

特別感謝deduce 提供資訊與E-Office 上的berlinch2000 讓我注意這塊
繼續閱讀全文 Wiimote 實現Multi-touch 與3D 的特別報導

ThreadPool.QueueUserWorkItem (new WaitCallback... 的意思

由 FUNction 於 2007年12月26日 上午11:14 發表
嘖...我又看不懂了
ThreadPool.QueueUserWorkItem (new WaitCallback... 這是什麼意思
從"毛毛的小窩—勤奮人生絢麗生活"找到的資料
(http://www.cnblogs.com/mjgforever/archive/2007/05/16/748505.html) [簡體]
我將之用Google 翻譯成正體,再替換掉一些專有名詞(應該有比較平易近人才對)

1) ThreadPool 類別,提供一個執行緒池,可用於發送工作項、處理非同步I/O、代表其他執行緒等待以及處理計時器。
許多應用程式創建的執行緒都要在休眠狀態中消耗大量時間,以等待事件發生。其他執行緒可能進入休眠,只被定期喚醒以輪流更改或更新狀態訊息。執行緒池通過為應用程序提供一個由系統管理的輔助執行緒池,使我們可以更為有效的使用執行緒。一個執行緒監視排到執行緒池的若干個等待操作的狀態。當一個等待操作完成時,執行緒池中的一個輔助執行緒就會執行對應的回調函數。值得注意的是:託管執行緒池中的執行緒為後台執行緒,即它們的IsBackground 屬性為true。這意味著在所有的前台執行緒都已退出後,執行緒池的執行緒不會讓應用程式保持運行。

我們也可以將與等待操作不相關的工作項排列到執行緒池。若要請求由執行緒池中的一個執行緒來處理工作項,就要使用QueueUserWorkItem 方法。此方法將對將被從執行緒池中選定的執行緒使用的方法或委託的引用用作參數。一個工作項排入佇列後就無法再取消它。

計時器佇列中的計時器以及已註冊的等待操作也使用執行緒池。它們的回調函數也會排列到執行緒池。

每個程序都有一個執行緒池。執行緒池的預設大小為每個可用程序有25個執行緒。 使用SetMaxThreads方法可以更改執行緒池中的執行緒數。每個執行緒使用預設的堆疊大小並按照預設的優先順序運行。

2) WaitCallback 委託表示執行緒池執行緒要執行的傳回方法。
WaitCallback 表示要在執行緒池中的執行緒上執行的傳回方法。創建委託,方法是將傳回方法傳遞給WaitCallback 建構函數。我們的方法必須具有此處所顯示的簽名。

通過將WaitCallback 委託傳遞給ThreadPool.QueueUserWorkItem 來將任務排入佇列以便執行。我們的傳回方法將在某個執行緒池中的執行緒可用時執行。

如果要將資訊傳遞給傳回方法,請創建包含所需資訊的對象,並在將任務排入佇列以便執行時將它傳遞給QueueUserWorkItem。每次執行您的傳回方法時,state 參數都包含此對象。

有關如何使用傳回同步執行緒池執行緒的更多資訊,請參見託管執行緒池。

3) ThreadPool.QueueUserWorkItem 方法 將方法排入隊列以便執行,並指定包含該方法所用數據的對象。
此方法在有執行緒池中的執行緒變得可用時執行。

在程式中我們通常會看到ThreadPool.QueueUserWorkItem (new WaitCallback(someMethod), someHandle) 這樣的語法,剛剛那個大陸Blog 也有程式範例。其他的資料請參考MSDN囉:http://msdn2.microsoft.com/zh-tw/library/system.threading.threadpool.aspx
繼續閱讀全文 ThreadPool.QueueUserWorkItem (new WaitCallback... 的意思

C#的 enum, EventHeader, [STAThread]

由 FUNction 於 2007年12月21日 中午12:16 發表
之前不是說我在寫C#
可是其實是個C#廢物
看看簡單的code 就發現自己真的超弱...是不是其實不會寫程式,我不知道
好...現在來寫一些剛剛才看懂的東西(請不要笑)

我看不懂enum 以下...
public enum CompletionStatus{
Sucess,
Failure
}

我不知道enum是什麼型別,後來才發現...
enum 關鍵字用來宣告列舉型別 (Enumeration),是由一組名為列舉值清單的具名常數所構成的獨特型別。每個列舉型別都有基礎型別,此基礎型別可以是除了 char 型別以外的任何整數型別。列舉項目的預設基礎型別是 int。根據預設,第一個列舉值的值是 0,而每一個接下來的列舉值會遞增 1。例如:
enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri};
在這個列舉型別裡,Sat 是 0,Sun 是 1,Mon 是 2,等等。
參考:http://msdn2.microsoft.com/zh-tw/library/sbbt4032(VS.80).aspx

此外,我看不懂EventHander,以下...
public event EventHander<ProgressEventArgs> Progress;
後來才知道可以自訂事件處理
我們繼承現有的EventArgs寫成自定的ProgressEventArgs Class
以處理特別的事件
(這句話說得好玄,而且也看似沒錯...但其實是因為我一知半解)
參考:http://msdn2.microsoft.com/zh-tw/library/w369ty8x(VS.80).aspx

最後,我發某些程式開頭有[STAThread]
[STAThread]:這是因為某些類別只能用在設定為單一執行緒 Apartment (STA) 模式的執行緒中。若要使用這些類別,就要確定 Main 方法以STAThreadAttribute 屬性做為標記。
[Serializable]:還有這種,若物件必須被序列化,則要將之加在Main裡。"
參考:http://chuiwenchiu-arick.blogspot.com/2007_02_01_archive.html

這些對某些人來說也許很簡單,但是書上似乎不好找到 Orz
繼續閱讀全文 C#的 enum, EventHeader, [STAThread]