允許遠程調試的簡單易用的 debug 工具 AConsole

jopen 9年前發布 | 14K 次閱讀 AConsole 程序調試

因為需要實現了一個可以遠程調試的工具 AConsole,現在來分享給大家。

請去 https://www.gitHub.com/iKCourage/iSunday 獲取 iSunday.exe 和 ingz 目錄下的 imoon_plugins.ingz 和 AConsole.ingz,并依次安裝。然后就可以打開桌面上的 AConsole.ing 了。

特性支持:

        通過 Socket (TCP) 連接進行調試:

                但過程中可以斷開連接,使用一個名字標識會話,即使調試過程中連接意外斷開也可以繼續調試。

                使用 JSON 字符串來發送消息(盡可能的簡單高效)。

        多標簽調試:

                支持多個應用程序同時進行調試,每一個都會打開新的標簽頁。

                可以是多個不同的應用程序。

        日志信息可以設置類別,會顯示成不同的顏色:

                可以通過自定義配置來區分消息,自定義的配置相當簡單,只是一個數字和對應的顏色。

                發送的消息里也需要描述一個數字(但這足夠簡單,因為使用 JSON,所以只是一個字段數值)。

        執行對象標記:

                同一個應用程序中的每一條消息都可以指定一個執行對象(用來描述是誰發送了這條消息,如:類名或方法名),然后可以使用快速過濾。

                推薦使用此項,因為這會使顯示更整齊,并且過濾起來更快。

                發送的消息里需要描述一個字符串。

        過濾系統:

                通過字符串或正則進行匹配消息,可以指定查找部分(執行對象部分,或消息部分)。

                還可以根據類別來過濾,如:普通消息,警告,錯誤等。

                一直覺得日志內容就應該支持查找的嘛。

        自動打開應用程序:

                這一項有些泛泛。可以通過配置自己的執行文件進行自動化編譯或調試,然后會每隔一定時間檢查一次是否有文件的狀態發生變化,如果發生,則調用系統 api 打開自定義的執行文件(并可添加執行參數),從而實現自動化。(此功能比較雞肋,很多人都實現了,不過還是帶著吧,有些時候確實很好用)

                可以同時支持多個執行文件和參數。

                可以自己配置合適的檢查時間。

大家可以通過自定義類別來設定一個適合自己的顯示規則,從而方便調試,就像給 IDE 配色一樣(總有自己喜歡的)。

然后可以直接看示例部分了。

另外贈送的功能(不是人人都會用到,希望可以幫到需要的人):

        在 Socket 里實現了一個簡單的輔助服務器,可以用來進行一些簡單的測試。

                如:需要模擬真實多用戶登錄的時候,可以每個應用程序都連接服務器,然后會獲得一個 id,然后通過此 id 定位已經配置好的數組進行用戶名和密碼的登錄。

                實現的功能有:

                                建立連接時返回用戶 id,id 是可以回收的,當有連接斷開時,該 id 將被回收。通過此可以模擬多個真實用戶。

                                建立連接時可以指定用戶所在的組 id,然后會返回組內的用戶 id。通過此可以將這個單服務器變成多服務器,每個組都互不影響,從而可以支持多個互不相關的程序同時進行調試。

                                當有新用戶進入時,廣播給所有已經建立連接的用戶(包含組 id 和用戶 id)。

                                當有新用戶斷開時,廣播給所有已經建立連接的用戶(包含組 id 和用戶 id)。

                                通過服務器廣播回來的其他用戶的 id,應用程序間就可以進行通信啦。如:轉發,或者廣播。并且支持轉發,廣播給一個或多個用戶,甚至是不同組的一個或多個用戶。(調侃一下:貌似是沒必要有的功能)

                                可以進行簡單的數據寫入和讀取,從而進行用戶間的數據共享。如:id 為 1 的用戶將共享數據寫入到服務器,然后 id 為 2 的用戶可以向服務器索取 id 為 1 的用戶的數據。(實現此功能時,我正好在寫 p2p 的東西,而外網服務器每次都會返回一個隨機的 64 位的 id,當兩個用戶進行連接時需要通過這個 64 位長的 id,煩擾之余就實現了這么個功能。我可以通過一個數字進行對話了。)當然,不一定大家都會用到,不過如果你湊巧需要的話,希望可以幫到你。

                                注:所有服務器返回的消息(或廣播)都可以忽略不進行處理。你只需要實現自己需要的功能就好了(發送或者接收)。更方便大家進行測試。

        一個簡單的 JSON 編輯和校驗工具。

        一個批量文件復制工具。即使從事文職工作也能使用。(復制文件時可以通過正則表達式進行過濾來復制一部分內容。通過正則表達式可以實現非常強大的復制規 則,不過有些學習成本。幸好大家不太可能會有這種需求,這種需求很少見。在這里寫出來不是告訴你這個功能多么好,而是希望在大家需要的時候可以幫到大 家。)

示例:

        消息格式:

                {"name": "player", "title": "播放器", "executor": "[WHERE]", "type": "print", "data": “message”, "_type": 0}

                        name: 一定要有(就像網頁里的 url,會通過這里來打開一個標簽頁)

        title: 標題

        executor: 執行者(什么地方執行的,可以沒有,但會使用一個默認的。通過這里也可以快速查找消息)

        type: "print" 打印消息(內容恒為 print)

        data: 消息內容(可以是字符串,也可以是數組,會自動轉換為字符串。在外部設計的時候可以使用變參方式,而不用拼接字符串)

        _type: 消息的類型(可以自定義任何類型,然后就可以通過過濾來查看指定類型的消息了。如果沒有,則使用默認 0)

        好了,這就是通過 Scoket 發送的消息內容,很簡單明了吧。

        Socket 發送格式:

                4 字節的包頭,一個 int。(標識后面這個包的字節大小,避免粘包)

                4 字節的通信標識 。(恒為數字 7)(大家不要糾結這里哈,沒必要用 4 個字節,但這樣大家用起來都方便不是么。)

                UTF 的字符串字節。

                注:4 字節的包頭只包含后面數據內容的大小,不包含這里的 4 個字節的包頭。

        這樣就可以進行調試了,還算簡單吧。

你也看到了,調試時的通信標識恒為 7,因為 0 - 6 已經用來實現 Socket 服務器的其他功能了。調試的時候只需要發送消息就可以了,不用管服務器的返回值(希望能簡單一點,其實也沒有必要哈)。不過服務器依然會返回標識為 7 的數據,用來通知你反送成功了(如果你需要的話)。

好了,來簡單介紹下所有的標識吧,大家可以直接看標識為 7 的內容。

說明:以下 >> 為發送的數據,<< 為服務器返回的數據。

        >> 0:客戶端注冊用戶,即讓服務器返回一個 id

                bytes.writeInt(4 + 4);

                bytes.writeInt(CSEnum.INIT);              // 此數值為 0

                bytes.writeInt(group);                         // 用戶所在組的 id,由用戶自己指定,可以不發送(默認為 0)只發送標識

                socket.writeBytes(bytes);

                socket.flush();

        << 0:服務器返回給用戶一個 id

                bytes.writeInt(4 + 4);                           // 服務器也返回一個包頭

                bytes.writeInt(CSEnum.INIT);               // 0

                bytes.writeInt(id);                                // 用戶的 id(之所以沒有返回用戶的組 id 是因為用戶自己知道)

                socket.writeBytes(bytes);

                socket.flush();

        << 3:服務器廣播給所有人新注冊用戶的組 id 和用戶 id

                bytes.writeInt(4 + 4 + 4);

                bytes.writeInt(CSEnum.INIT_ALL);

                bytes.writeInt(id);

                bytes.writeInt(group);

        >> 1:客戶端讀取其他用戶 id 的數據(也可以是自己的)

                bytes.writeInt(4 + 4 + 4);

                bytes.writeInt(CSEnum.READ);

                bytes.writeInt(id);

                bytes.writeInt(group);

        << 1:服務器返回給用戶讀取的數據

                bytes.writeInt(4 + data.length);

                bytes.writeInt(CSEnum.READ);

                bytes.writeBytes(data);

        >> 2:客戶端寫入自己的數據

                bytes.writeInt(4 + data.length);

                bytes.writeInt(CSEnum.WRITE);

                bytes.writeBytes(data);

        << 2:服務器返回寫入成功

                bytes.writeInt(4);

                bytes.writeInt(CSEnum.WRITE);

        << 4:服務器在有客戶端連接斷開時廣播給其他用戶

                bytes.writeInt(4 + 4 + 4);

                bytes.writeInt(CSEnum.CLOSE_ALL);

                bytes.writeInt(id);

                bytes.writeInt(group);

        >> 5:客戶端通過服務器來將消息轉發給其他人(這里有點復雜,因為轉發功能有點多,不需要就不用看了)

                接下來就有點麻煩了(其實很簡單,因為好多都用不到),先描述下轉發規則:

                0 所有組的所有人

                                bytes.writeInt(4 + 4 + data.length);

                                bytes.writeInt(CSEnum.RELAY);

                                bytes.writeInt(0);                                                       // 轉發規則標識

                                bytes.writeBytes(data);

1 默認組的幾個人

                                bytes.writeInt(4 + 4 + (4 + 4 * 3) + data.length);       // 4 * 3 為用戶的 id 占的字節,如:這里為 3,所以還得乘 4

                                bytes.writeInt(CSEnum.RELAY);

                                bytes.writeInt(1);                                                       // 轉發規則標識

                                bytes.writeInt(id.length);                                            // 這里為 3(用戶個數)

                                bytes.writeInt(2);                                                       // id 為 2 的用戶

                                bytes.writeInt(3);                                                       // id 為 3 的用戶

                                bytes.writeInt(4);                                                       // id 為 4 的用戶

                                bytes.writeBytes(data);

2 默認組的所有人

                                bytes.writeInt(4 + 4 + data.length);

                                bytes.writeInt(CSEnum.RELAY);

                                bytes.writeInt(2);                                                      // 轉發規則標識

                                bytes.writeBytes(data);

3 指定組的幾個人

                                bytes.writeInt(4 + 4 + (4 + 4 + 4 * 3) + data.length);

                                bytes.writeInt(CSEnum.RELAY);

                                bytes.writeInt(3);                                                      // 轉發規則標識

                                bytes.writeInt(id.length);

                                bytes.writeInt(group);

                                bytes.writeInt(2);                                                      // id 為 2 的用戶

                                bytes.writeInt(3);                                                      // id 為 3 的用戶

                                bytes.writeInt(4);                                                      // id 為 4 的用戶

                                bytes.writeBytes(data);

4 指定組的幾個人(每個人都分組)

                                bytes.writeInt(4 + 4 + (4 + 4 * 3 * 2) + data.length);

                                bytes.writeInt(CSEnum.RELAY);

                                bytes.writeInt(4);                                                      // 轉發規則標識

                                bytes.writeInt(id.length);

                                bytes.writeInt(2);                                                      // id 為 2 的用戶

                                bytes.writeInt(group_2);                                            // id 為 2 的用戶的組的 id

                                bytes.writeInt(3);                                                      // id 為 3 的用戶

                                bytes.writeInt(group_3);                                            // id 為 3 的用戶的組的 id

                                bytes.writeInt(4);                                                      // id 為 4 的用戶

                                bytes.writeInt(group_4);                                            // id 為 4 的用戶的組的 id

                                bytes.writeBytes(data);

5 指定組的所有人

                                bytes.writeInt(4 + 4 + data.length);

                                bytes.writeInt(CSEnum.RELAY);

                                bytes.writeInt(5);                                                      // 轉發規則標識

                                bytes.writeInt(group);                                               // 指定的組的 id

                                bytes.writeBytes(data);

        << 6:服務器轉發給指定的用戶

                bytes.writeInt(4 + 4 + 4 + data.length);

                bytes.writeInt(CSEnum.RELAY_BACK);

                bytes.writeInt(index);

                bytes.writeInt(group);

                bytes.writeBytes(data);

        >> 7:客戶端發送給服務器的日志信息(大家用這里就好了,上面的我寫著都好煩啊)

                bytes.writeInt(4 + strBytes.length);

                bytes.writeInt(CSEnum.SEND);

                bytes.writeBytes(strBytes);

        << 7:服務器返回發送成功

                bytes.writeInt(4);

                bytes.writeInt(CSEnum.SEND);

終于把 Socket 寫完了。之所以寫這么多,是希望可以幫到需要的人。

Socket 默認偵聽 9000 和 9001。9001 是安全策略文件的偵聽,會返回一個安全策略 XML,某些應用程序可能會用到,大部分不需要。

還有一個是關于自動打開應用程序的配置的,大家可以去看配置文件,里面有詳細的注釋,這里已經說很多了,就不說了。

然后上幾張截圖給大家哈:

允許遠程調試的簡單易用的 debug 工具 AConsole

允許遠程調試的簡單易用的 debug 工具 AConsole

允許遠程調試的簡單易用的 debug 工具 AConsole

允許遠程調試的簡單易用的 debug 工具 AConsole

來自:http://my.oschina.net/courage/blog/369946

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!