前幾天,實驗室的碩三學長去註冊中研院的 「中文斷詞系統」,先不論這個系統除了功能以外,回傳資料都很不 Friendly (),這個系統連接是用 TCP 來連接,思考過可能會透過其他地方存取這個 API ,所以把他分開來寫在另一個伺服器 PHP 腳本上。

專案: https://github.com/hpcslag/CKIPUnity

PHP 錯誤

(Error: 找不到 create_socket) 的錯誤,很可能是你系統沒有打開 php-socket 這個模組,你可以去 PHP 官網下載 php-socket.dll 檔案(雖然不曉得你應該從哪下載,反正有就好),把它塞到 system32 或是 PHP 目錄下應該都可以解決。

API Key

PHP的程式碼是直接透過帳號密碼來建立 TCP 連接,隨意被存取恐怕也是不好的事情,加上一個 $api_key 來管理就行了。

$api_key = "asdfasdf";

if($_POST["api_key"] != $api_key){  
    echo "{\"error\":\"true\",\"errorMsg\":\"API Key failed.\"}";
    return;
}else{
...
}

Unity WWW 類別來存取

我一直都想用同步的方式來下載 API 資料,這個方法相當不適合使用,嘗試了一天還是改用異步來下載。

Unity WWW 本身就要跑 IEnumerator 線程,要用 MonoBehaviour 的 StartCoroutine 來解決,所以設計新的類別來管理也要傳喚 MonoBehaviour 過來。

public CKIPUnity(string api_key,MonoBehaviour mono){  
    this.api_key = api_key;
    this.mono = mono;
}

C# 可以用 delegate 做到事件觸發、callback...隨你怎麼講,的那種效果。

public delegate void Receiver(string text);

public void getText(string text,Receiver _Receiver){  
    mono.StartCoroutine(
        RequestData(
            "Hello,my name is mac",
            "text",
            _Receiver
        )
    );
}

使用端的考慮

從有 WWW 同步的想法開始,就一直想著使用端到底如何操作比較方便,到最後設計只能用事件返回呼叫的方法,讓使用者自己實作不同事件應該如何處理,以下是使用端程式碼

void setup(){

  CKIPUnity ckip = new CKIPUnity ("asdfasdf",this);

  ckip.getSentence("昨天,有,一起,地震。",GetSentence);
}

//delegate function
private void GetSentence(string text){  
  Debug.Log(text);
}

實用工具 (Util tools)

目前只設計一個,解析結果的 XML 成 List<string> 用的 ParseXMLToList(string text)

List<string> list = CKIPUnity.ParseXMLToList(text);

string[] data = list.ToArray();

for (int i = 0; i < data.Length; i++) {  
  Debug.Log (data[i]);
}

測試 PHP API