Friday, December 7, 2007

Cloud Computing and GWT

(At the GWT Conference conclusion, someone asked about authoring apps that run on both GWT and Android, I promised I'd detail my findings here...)

One of the purported benefits of Microsoft Volta is "cloud computing" which is the ability to move code execution to different tiers in your application. Now, cloud computing is not really new per se, since mobile code platforms have been able to achieve this for some time with careful architecture, but Microsoft is presenting a vision of doing it painlessly and (relatively) automatically.

I'm of the opinion that it's probably achievable to do it in an automated fashion, but that you are going to hurt user experience. That's because the raw execution performance and I/O bandwidth of the client and server differ dramatically, and simply moving some business logic and data handling code from server to client without thinking about it is going to lead to plenty of pathologically bad cases. It's a case of trying too hard to plug holes in a leaky abstraction.

Choose an abstraction that leaks least


That said, if you are careful, you can do Cloud Computing with GWT and achieve code reuse without suffering too many performance gotchas or pathologically bad cases, but the design work has to be done up front, as it becomes alot harder later to unshackle dependencies and abstraction leaks from you code.

I don't profess to be an expert on this, but here is my experience from porting Chronoscope to several "clouds" (Mobile, JS, Flash, Java2D).

Know your clouds


First, do some up front legwork before you start coding. Hand code a prototype for each cloud to get an intuitive sense of each platform's performance and API support. Then choose a reasonable lowest-common-denominator in terms of API support and performance.

In the case of Chronoscope, I had written JS, Flash, and Java2d prototypes before I wrote the first line of GWT code.

Scaling APIs


Now that you know what your target minimum requirements are, you have two tasks. First, pick an abstraction that represents what's achievable on each of the platforms you're targeting to make sure enough API support is there to either support a feature directly, or emulate it with acceptable performance.

You may have to do several iterations of this to get it right. For example, with Chronoscope, I started out with the Safari/WHATWG Javascript canvas as my abstraction, but I needed text rendering (rotated as well), hit detection, Flash support, and the ability to not have to redraw unchanged portions of the screen.

I started by adding horizontal text rendering by placing DIVs over the Canvas, which of course has several problems (that I addressed later). I then noticed that to make Flash performant I need to ship a whole frame's worth of drawing commands to Flash in a batch. Moreover, Opera's Canvas incrementally updates the display while you're drawing, but they fixed this by adding a non-standard lockCanvasUpdates() function. This led to the addition of OpenGL-style DisplayList capability and a beginFrame()/endFrame() pair of methods.

I initially tried to emulate damage region painting everywhere, but it was too slow. It turns out creating lots of CANVAS elements or MovieClip objects in Flash is not that bad, so I introduced the concept of Layers (ala Photoshop), with a canvas.createLayer() call. The layer system also facilitates adding hit detection in a way which doesn't require alot of scenegraph-style overhead. I'm now confident that this is the right abstraction not only to support slow cloud platforms, but to leverage natively accelerated features of the various platforms.

Decoupling from GWT


Usage of any com.google.gwt.* classes is going to tie your code to running in the GWT cloud. Now, gwt-user is great and we want to use it, but do so in a way that allows it to be swapped out on other platforms.

For Chronoscope, I use the following techniques:

  • Stick to JRE Emulation classes as much as possible
  • GWT core classes can be reasonably abstracted (Timer, Network requests, etc)
  • Abstract away GWT Widgets where possible (MyMenuItem interface vs Menuitem)
  • Isolate all JSNI code into a browser specific impl package
  • Use a platform specific Factory/Toolkit to create implementation instances of various abstractions (in Chronoscope, this is called the View class)


Package layout


Here's the package layout I use:

  • org.timepedia.chronoscope.client - all 'cloud safe' code goes here and in subpackages
  • org.timepedia.chronoscope.browser - any class performing any operation that transitively requires gwt-user or JSNI goes here
  • org.timepedia.chronoscope.java2d - Java2D cloud specific Canvas implementation
  • org.timepedia.chronoscope.client.flash - Flash specific cloud code here
  • org.timepedia.chronoscope.android - Android specific View/Canvas stuff here
    org.timepedia.chronoscope.server - Servlet Chart Server stuff


Example Abstraction: Timers


Chronoscope does a lot of interpolated animations, and to do so, it needs the use of a timer. Usage of the GWT Timer class would not allow the code to run as an Applet or compile for Android, so instead, this is how timing is done in Chronoscope:

package org.timepedia.chronoscope.client.util;
/**
* Abstraction for running scheduled tasks, independent of JRE environment
*/
public interface PortableTimer {
public void cancelTimer();
public void schedule(int delayMillis);
public void scheduleRepeating(int periodMillis);
double getTime();
}

And of couse, the BrowserView factory class which returns instances that work in GWT:

/**
* Creates a PortableTimer based on GWT's Timer class.
*
* @param run
* @return
*/
public PortableTimer createTimer(final PortableTimerTask run) {
return new BrowserTimer() {

public void run() {
run.run(this);
}

public void cancelTimer() {
cancel();
}

public double getTime() {
return new Date().getTime();
}
};

}


I have created similar abstractions for menus, toolbars, and other things that Timepedia needs, and as I discover new widgets that are needed, I add 'cloud enabled' versions as I go along.

UI Widgets tend to have analogs on every platform that function slightly differently, but it's not hard to seek out minimalist lowest common denominator behavior.

Sometimes this approach fails


So far, I have discussed design techniques to make recompiling for the cloud relatively automatic and painless, but for reasons I cited in the beginning, as well as other fundamental differences, you cannot expect something to be write-once work everywhere. Here's some differences that will bit you:


  • JDK1.5 vs JDK1.4 language features (mostly fixed by GWT 1.5)
  • JRE Emul collections vs CLDC/J2ME
  • Pointing device/events. Not every platform will have gamepad keys, support double-click, single click, drag, etc. The iPhone being the biggest example.
  • Network security policies (no access, extremely slow access, same domain access, full access) Sometimes remedied by proxies, but usually a pain in the ass no matter what.


When abstraction fails...


Maintain two branches of your codebase. I do this for J2ME due to CLDC <-> JRE Emul conflicts. I also do it for UI event handling, as each application has to be tailored for the screen format and keyboard/input device of each platform. Years of mobile industry development have taught me the painful fallacy of trying to devise a general purpose app that is not device specific. Want the best user experience? You have to tailor for form-factor and input device.

A preprocessor can sometimes come to the rescue (Foo/*<Bar>*/ -> Foo<Bar> on 1.5+ platforms, Retroweaver can help smooth over 1.5->1.4 collection issues, and there are hacks/tools to inject 1.1 style collection interfaces into J2ME platforms that lack them, such as JDiet)

Future Directions


Both GWT and Android are moving towards compile time declarative UIs, it may be possible in the near future to create a unified declarative UI syntax that allows code generation for both GWT widget layouts and Android.

That's about all I can think of to say on the subject right now. GWT permits Cloud Computing, it was one of the reasons I chose it, and if you're interested in building components that can live within GWT and Android, it is certainly possible.

-Ray

p.s. some might technically quibble and say it's not true cloud computing because all of the tiers I consider are client-side platforms, but Chronoscope does run on the server too, and I can generate old Web 1.0 style image-map interfaces for navigation (JFreeChart can do this as well)

7 comments:

Deva said...

Ray, I was the one who asked about GWT development for Android - Thanks for the very informative article - I will be checking out your blog in a regular basis.

Oh and Thanks for Deferred Binding slides too :) --Deva.

sexy said...

情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣,情趣,情趣,情趣,情趣,情趣,情趣用品,情趣用品,情趣,情趣,A片,A片,A片,A片,A片,A片,情趣用品,A片,情趣用品,A片,情趣用品,a片,情趣用品,視訊聊天室,聊天室,視訊,ut聊天室,聊天室,視訊聊天室,成人電影,

A片,A片,AV女優,色情,成人,做愛,情色,AIO,視訊聊天室,SEX,聊天室,自拍,AV,情色,成人,情色,aio,sex,成人,情色,色情,情色電影,色情網站,av女優,av,自拍,成人,視訊聊天室,視訊交友網,AV女優,成人,聊天室,ut聊天室,av女優

免費A片,美女視訊,情色交友,免費AV,色情網站,辣妹視訊,美女交友,色情影片,成人影片,成人網站,H漫,18成人,成人圖片,成人漫畫,情色網,日本A片,免費A片下載,性愛

色情A片,A片下載,色情遊戲,色情影片,色情聊天室,情色電影,免費視訊,免費視訊聊天,免費視訊聊天室,一葉情貼圖片區,情色視訊,免費成人影片,視訊交友,視訊聊天,言情小說,愛情小說,AV片,A漫,av dvd,情色論壇,視訊美女,AV成人網,情色文學,成人交友,成人電影,成人貼圖,成人小說,成人文章,成人圖片區,成人遊戲,愛情公寓,情色貼圖,成人論壇,色情


免費A片,日本A片,A片下載,線上A片,成人電影,嘟嘟成人網,成人貼圖,成人交友,成人圖片,18成人,成人小說,成人圖片區,微風成人區,成人文章,成人影城,情色貼圖,色情聊天室,情色視訊,情色文學,色情小說,情色小說,臺灣情色網,色情遊戲,嘟嘟情人色網,麗的色遊戲,情色論壇,一葉情貼圖片區,做愛,性愛,美女視訊,辣妹視訊,免費視訊聊天,美女交友,做愛影片

said...

A片,A片,成人網站,成人漫畫,色情,情色網,情色,AV,AV女優,成人影城,成人,色情A片,日本AV,免費成人影片,成人影片,SEX,免費A片,A片下載,免費A片下載,做愛,情色A片,色情影片,H漫,A漫,18成人

a片,色情影片,情色電影,a片,色情,情色網,情色,av,av女優,成人影城,成人,色情a片,日本av,免費成人影片,成人影片,情色a片,sex,免費a片,a片下載,免費a片下載

情趣用品,情趣用品,情趣,情趣,情趣用品,情趣用品,情趣,情趣,情趣用品,情趣用品,情趣,情趣

A片,A片,A片下載,做愛,成人電影,.18成人,日本A片,情色小說,情色電影,成人影城,自拍,情色論壇,成人論壇,情色貼圖,情色,免費A片,成人,成人網站,成人圖片,AV女優,成人光碟,色情,色情影片,免費A片下載,SEX,AV,色情網站,本土自拍,性愛,成人影片,情色文學,成人文章,成人圖片區,成人貼圖

情色,AV女優,UT聊天室,聊天室,A片,視訊聊天室


UT聊天室,視訊聊天室,辣妹視訊,視訊辣妹,情色視訊,視訊,080視訊聊天室,視訊交友90739,美女視訊,視訊美女,免費視訊聊天室,免費視訊聊天,免費視訊,視訊聊天室,視訊聊天,視訊交友網,視訊交友,情人視訊網,成人視訊,哈啦聊天室,UT聊天室,豆豆聊天室,
聊天室,聊天,色情聊天室,色情,尋夢園聊天室,聊天室尋夢園,080聊天室,080苗栗人聊天室,柔情聊天網,小高聊天室,上班族聊天室,080中部人聊天室,中部人聊天室,成人聊天室,成人

清朝美女 said...

(法新社倫敦四日電) 英國情色大亨芮孟的公司a片昨天a片下載說,芮孟日前去世,享壽八十二歲;這位身價上億的房地產開發商,曾經在倫敦av女優推出第一情色視訊成人影片脫衣舞表演。色情
av情色電影
情色
芮孟的av女優財產av估計達六億五千萬英鎊(台幣將近四百億),由日本av於他名下事業大多分布在倫敦夜生活區蘇活區,因色情影片成人擁有「蘇活之王」的稱號。成人網站


他的公司「保羅芮情色孟集團」旗下發行部落格多種情色雜誌,包成人網站括「Razzle」、「男性世界」以及「Ma部落格yfair」。


芮孟成人電影本名傑福瑞a片.安東尼.奎恩,父親為搬成人光碟運承包商。成人影片芮孟十五成人網站歲離開學av女優校,矢言要在表成人演事業留名,起先表演讀成人影片心術,後來成為巡迴av歌舞雜耍表sex演的製a片作人。


許多評論家認為,他把情色表演帶進主流社會a片,一九五九年主持破天荒的脫衣舞表演情色電影,後來更AV片靠著在蘇avdvd活區與倫部落格敦西區開發房成人電影地產賺得色情a片大筆財富。

色情
有人形容芮孟av是英a片下載國的海夫色情納,地位等同美國的「花花公子」創辦人海夫納。

信次 said...

情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,美國aneros,rudeboy,英國rudeboy,英國Rocksoff,德國Fun Factory,Fun Factory,英國甜筒造型按摩座,甜筒造型按摩座,英國Rock Chic ,瑞典 Lelo ,英國Emotional Bliss,英國 E.B,荷蘭 Natural Contours,荷蘭 N C,美國 OhMiBod,美國 OMB,Naughti Nano ,音樂按摩棒,ipod按摩棒,美國 The Screaming O,美國TSO,美國TOPCO,美國Doc Johnson,美國CA Exotic,美國CEN,美國Nasstoy,美國Tonguejoy,英國Je Joue,美國Pipe Dream,美國California Exotic,美國NassToys,美國Vibropod,美國Penthouse,仿真按摩棒,矽膠按摩棒,猛男倒模,真人倒模,仿真倒模,PJUR,Zestra,適趣液,穿戴套具,日本NPG,雙頭龍,FANCARNAL,日本NIPPORI,日本GEL,日本Aqua Style,美國WET,費洛蒙,費洛蒙香水,仿真名器,av女優,打炮,做愛,性愛,口交,吹喇叭,肛交,魔女訓練大師,無線跳蛋,有線跳蛋,震動棒,震動保險套,震動套,TOY-情趣用品,情趣用品網,情趣購物網,成人用品網,情趣用品討論,成人購物網,鎖精套,鎖精環,持久環,持久套,拉珠,逼真按摩棒,名器,超名器,逼真老二,電動自慰,自慰,打手槍,仿真女郎,SM道具,SM,性感內褲,仿真按摩棒,pornograph,hunter系列,h動畫,成人動畫,成人卡通,情色動畫,情色卡通,色情動畫,色情卡通,無修正,禁斷,人妻,極悪調教,姦淫,近親相姦,顏射,盜攝,偷拍,本土自拍,素人自拍,公園露出,街道露出,野外露出,誘姦,迷姦,輪姦,凌辱,痴漢,痴女,素人娘,中出,巨乳,調教,潮吹,av,a片,成人影片,成人影音,線上影片,成人光碟,成人無碼,成人dvd,情色影音,情色影片,情色dvd,情色光碟,航空版,薄碼,色情dvd,色情影音,色情光碟,線上A片,免費A片,A片下載,成人電影,色情電影,TOKYO HOT,SKY ANGEL,一本道,SOD,S1,ALICE JAPAN,皇冠系列,老虎系列,東京熱,亞熱,武士系列,新潮館,情趣用品,情趣,情趣商品,情趣網站,跳蛋,按摩棒,充氣娃娃,自慰套,G點,性感內衣,情趣內衣,角色扮演,生日禮物,生日精品,自慰,打手槍,潮吹,高潮,後庭,情色論譠,影片下載,遊戲下載,手機鈴聲,音樂下載,開獎號碼,統一發票號碼,夜市,統一發票對獎,保險套,做愛,減肥,美容,瘦身,當舖,軟體下載,汽車,機車,手機,來電答鈴,週年慶,美食,徵信社,網頁設計,網站設計,室內設計,靈異照片,同志,聊天室,運動彩券,大樂透,威力彩,搬家公司,除蟲,偷拍,自拍,無名破解,av女優,小說,民宿,大樂透開獎號碼,大樂透中獎號碼,威力彩開獎號碼,討論區,痴漢,懷孕,美女交友,交友,日本av,日本,機票,香水,股市,股市行情, 股市分析,租房子,成人影片,免費影片,醫學美容,免費算命,算命,姓名配對,姓名學,姓名學免費,遊戲,好玩遊戲,好玩遊戲區,線上遊戲,新遊戲,漫畫,線上漫畫,動畫,成人圖片,桌布,桌布下載,電視節目表,線上電視,線上a片,線上掃毒,線上翻譯,購物車,身分證製造機,身分證產生器,手機,二手車,中古車,法拍屋,歌詞,音樂,音樂網,火車,房屋,情趣用品,情趣,情趣商品,情趣網站,跳蛋,按摩棒,充氣娃娃,自慰套, G點,性感內衣,情趣內衣,角色扮演,生日禮物,精品,禮品,自慰,打手槍,潮吹,高潮,後庭,情色論譠,影片下載,遊戲下載,手機鈴聲,音樂下載,開獎號碼,統一發票,夜市,保險套,做愛,減肥,美容,瘦身,當舖,軟體下載,汽車,機車,手機,來電答鈴,週年慶,美食,徵信社,網頁設計,網站設計,室內設計,靈異照片,同志,聊天室,運動彩券,,大樂透,威力彩,搬家公司,除蟲,偷拍,自拍,無名破解, av女優,小說,民宿,大樂透開獎號碼,大樂透中獎號碼,威力彩開獎號碼,討論區,痴漢,懷孕,美女交友,交友,日本av ,日本,機票,香水,股市,股市行情,股市分析,租房子,成人影片,免費影片,醫學美容,免費算命,算命,姓名配對,姓名學,姓名學免費,遊戲,好玩遊戲,好玩遊戲區,線上遊戲,新遊戲,漫畫,線上漫畫,動畫,成人圖片,桌布,桌布下載,電視節目表,線上電視,線上a片,線上a片,線上翻譯,購物車,身分證製造機,身分證產生器,手機,二手車,中古車,法拍屋,歌詞,音樂,音樂網,借錢,房屋,街頭籃球,找工作,旅行社,六合彩,整型,整型,珠海,雷射溶脂,婚紗,網頁設計,水噹噹,台中隆鼻,果凍隆乳,改運整型,自體脂肪移植,新娘造型,婚禮顧問,下川島,常平,常平,珠海,澳門機票,香港機票,貸款,貸款,信用貸款,宜蘭民宿,花蓮民宿,未婚聯誼,網路購物,婚友,婚友社,未婚聯誼,交友,婚友,婚友社,單身聯誼,未婚聯誼,未婚聯誼, 婚友社,婚友,婚友社,單身聯誼,婚友,未婚聯誼,婚友社,未婚聯誼,單身聯誼,單身聯誼,白蟻,白蟻,除蟲,老鼠,減肥,減肥,在家工作,在家工作,婚友,單身聯誼,未婚聯誼,婚友,交友,交友,婚友社,婚友社,婚友社,大陸新娘,大陸新娘,越南新娘,越南新娘,外籍新娘,外籍新娘,台中坐月子中心,搬家公司,搬家公司,中和搬家,台北搬家,板橋搬家,新店搬家,線上客服,網頁設計,線上客服,網頁設計,植牙,關鍵字,關鍵字,seo,seo,網路排名,自然排序,網路排名軟體,交友,越南新娘,婚友社,外籍新娘,大陸新娘,越南新娘,交友,外籍新娘,視訊聊天,大陸新娘,婚友社,婚友,越南新娘,大陸新娘,越南新娘,視訊交友,外籍新娘,網路排名,網路排名軟體,網站排名優化大師,關鍵字排名大師,網站排名seo大師,關鍵字行銷專家,關鍵字,seo,關鍵字行銷,網頁排序,網頁排名,關鍵字大師,seo大,自然排名,網站排序,網路行銷創業,汽車借款,汽車借錢,汽車貸款,汽車貸款,拉皮,抽脂,近視雷射,隆乳,隆鼻,變性,雙眼皮,眼袋,牙齒,下巴,植牙,人工植牙,植髮,雷射美容,膠原蛋白,皮膚科,醫學美容,玻尿酸,肉毒桿菌,微晶瓷,電波拉皮,脈衝光,關鍵字,關鍵字,seo,seo,網路排名,自然排序,網路排名軟體,汽車借款,汽車借款,汽車借款,汽車貸款,汽車貸款,借錢,借貸,當舖,借款,借貸,借錢,週轉,學英文,英文社團,英語俱樂部,學習英文,英語會話,英文演講,English Club,學英語,學英文,美語社團,英語社團,英文讀書會,Toastmasters,Toastmaster,英語讀書會,拍樂得批發,拍樂得飾品,拍樂得化妝品批發,

海盜 said...

成人網站,av女優,成人網站,a片,成人影片,h漫,成人電影,成人電影,色情,成人影片,免費A片,色情,成人影片,色情,免費A片,微風成人,情色,成人網站,av女優,成人網站,a片,成人影片,h漫,色情,成人電影,色情,成人電影,色情,成人影片,免費A片,成人影片,免費A片,情色,微風成人,成人網站,av女優,成人網站,a片,成人影片,h漫,成人電影,成人電影,色情,成人影片,免費A片,色情,成人影片,色情,免費A片,





微風成人,情色,成人網站,av女優,成人網站,a片,成人影片,h漫,色情,成人電影,色情,成人電影,色情,成人影片,免費A片,成人影片,免費A片,情色,微風成人,情趣用品,情趣用品,情趣用品,情趣用品,打卡鐘,跳蛋,持久液,成人網站,成人網站,成人網站,成人網站,色情網站,色情網站,色情網站,色情網站,av女優,av女優,av女優,av女優,色情,色情,色情,色情,h漫,h漫,h漫,h漫,sex,sex,sex,sex,成人影片,成人影片,成人影片,成人影片,成人電影,成人電影,成人電影,成人電影,av女優,a片,a片,a片,a片,成人網站,







成人網站,成人網站,成人網站,成人影片,成人影片,成人影片,成人影片,av女優,av女優,av女優,av女優,色情,色情,色情,色情,h漫,h漫,h漫,h漫,sex,sex,sex,sex,情色,情色,情色,情色,黃金回收,黃金回收,黃金回收,黃金回收,借錢,借錢,借錢,借錢,植牙,植牙,植牙,牙醫,牙醫,牙醫,a片,a片,a片,a片,情趣用品,情趣用品,情趣用品,情趣用品,成人網站,成人網站,成人網站,成人網站,成人影片,成人影片,



成人影片

,成人影片,av女優,av女優,av女優,av女優,色情,色情,色情,色情,h漫,h漫,h漫,h漫,sex,sex,sex,sex,情色,情色,情色,情色,黃金,黃金,黃金,黃金,黃金價格,黃金價格,黃金價格,黃金價格,黃金買賣,黃金買賣,黃金買賣,黃金買賣,當舖,當舖,當舖,當舖,鑽石價格,鑽石價格,鑽石價格,鑽石價格,鑽石回收,鑽石回收,鑽石回收,鑽石回收,鑽石買賣,鑽石買賣,鑽石買賣,鑽石買賣,黃金存摺,黃金存摺,黃金存摺,







黃金存摺,辣妹視訊,辣妹視訊,辣妹視訊,辣妹視訊,080視訊聊天室,080視訊聊天室,080視訊聊天室,080視訊聊天室,美女交友,美女交友,美女交友,美女交友,情色視訊,情色視訊,情色視訊,情色視訊,哈啦聊天室,哈啦聊天室,哈啦聊天室,哈啦聊天室,ut聊天室,ut聊天室,ut聊天室,ut聊天室,聊天室,聊天室,聊天室,打卡鐘,火鍋吃到飽,創業加盟,賺錢,吃到飽麻辣鍋成人網站,成人影片,av女優,h漫,成人網站,成人電影,a片,色情,成人影片,色情,成人電影,色情,h漫,成人影片,成人電影,免費A片,色情,成人電影,成人影片,免費A片,色情,成人網站,免費A片,成人網站,色情,a片,成人影片,情色,免費A片,微風成人,情色,成人影片,微風成人,av女優

平平 said...

^^ nice blog!! ^@^

徵信, 徵信網, 徵信社, 徵信社, 徵信社, 徵信社, 感情挽回, 婚姻挽回, 挽回婚姻, 挽回感情, 徵信, 徵信社, 徵信, 徵信, 捉姦, 徵信公司, 通姦, 通姦罪, 抓姦, 抓猴, 捉猴, 捉姦, 監聽, 調查跟蹤, 反跟蹤, 外遇問題, 徵信, 捉姦, 女人徵信, 女子徵信, 外遇問題, 女子徵信, 徵信社, 外遇, 徵信公司, 徵信網, 外遇蒐證, 抓姦, 抓猴, 捉猴, 調查跟蹤, 反跟蹤, 感情挽回, 挽回感情, 婚姻挽回, 挽回婚姻, 外遇沖開, 抓姦, 女子徵信, 外遇蒐證, 外遇, 通姦, 通姦罪, 贍養費, 徵信, 徵信社, 抓姦, 徵信社, 徵信, 徵信公司, 徵信社, 徵信, 徵信公司, 徵信社, 徵信公司, 女人徵信, 外遇

徵信, 徵信網, 徵信社, 徵信網, 外遇, 徵信, 徵信社, 抓姦, 徵信, 女人徵信, 徵信社, 女人徵信社, 外遇, 抓姦, 徵信公司, 徵信社, 徵信社, 徵信社, 徵信社, 徵信社, 徵信社, 女人徵信社, 徵信社, 徵信, 徵信社, 徵信, 女子徵信社, 女子徵信社, 女子徵信社, 女子徵信社, 徵信, 徵信社, 徵信, 徵信社, 徵信, 徵信社, 徵信, 徵信社, 徵信, 徵信社, 徵信, 徵信社, 徵信社,

徵信, 徵信社,徵信, 徵信社, 徵信, 徵信社, 徵信, 徵信社, 徵信, 徵信社, 徵信, 徵信社, 徵信, 徵信社, 徵信, 徵信社, 徵信, 徵信社, 徵信, 徵信社, 徵信, 徵信社, 徵信, 徵信社, 徵信, 徵信社, 徵信, 徵信社, 徵信, 徵信社, 徵信, 徵信社, 徵信, 徵信社, 外遇, 抓姦, 離婚, 外遇,離婚,

徵信, 外遇, 離婚, 徵信社, 徵信, 外遇, 抓姦, 徵信社, 徵信, 徵信社, 徵信, 外遇, 徵信社, 徵信, 外遇, 抓姦, 徵信社, 征信, 征信, 徵信, 徵信社, 徵信, 徵信社, 征信, 徵信, 徵信社, 徵信, 徵信社, 徵信, 徵信社, 徵信, 徵信社, 徵信社, 徵信社, 徵信, 外遇, 抓姦, 徵信, 徵信社, 徵信, 徵信社, 徵信,