亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > XML > 正文

通過壓縮SOAP改善XML Web service性能

2024-09-05 20:56:01
字體:
來源:轉載
供稿:網友


壓縮文本是一個可以減少文本內容尺寸達80%的過程。這意味著存儲壓縮的文本將會比存儲沒有壓縮的文本少80%的空間。也意味著在網絡上傳輸內容需要更少的時間,對于使用文本通信的客戶端服務器應用程序來說,將會表現出更高的效率,例如xml web services。

本文的主要目的就是尋找在客戶端和服務器之間使交換的數據尺寸最小化的方法。一些有經驗的開發者會使用高級的技術來優化通過網絡特別是互聯網傳送的數據,這樣的做法在許多分布式系統中都存在瓶頸。解決這個問題的一個方法是獲取更多的帶寬,但這是不現實的。另一個方法是通過壓縮的方法使得被傳輸的數據達到最小。

當內容是文本的時候,通過壓縮,它的尺寸可以減少80%。這就意味著在客戶端和服務器之間帶寬的需求也可以減少類似的百分比。為了壓縮和解壓縮,服務端和客戶端則占用了cpu的額外資源。但升級服務器的cpu一般都會比增加帶寬便宜,所以壓縮是提高傳輸效率的最有效的方法。

xml/soap在網絡中

讓我們仔細看看soap在請求或響應xml web service的時候,是什么在網絡上傳輸。我們創建一個xml web service,它包含一個 add 方法。這個方法有兩個輸入參數并返回這兩個數的和:

<webmethod()> public function add(byval a as integer, byval b as _integer) as integer
add = a + b
end function

當 xml web service 消費端調用這個方法的時候,它確實發送了一個soap請求到服務器:

<?xml version="1.0" encoding="utf-8"?>
<soap:envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
xmlns:xsd="http://www.w3.org/2001/xmlschema">
<soap:body><add xmlns="http://tempuri.org/"><a>10</a><b>20</b></add>
</soap:body></soap:envelope>

服務端使用一個soap響應來回應這個soap請求:

<?xml version="1.0" encoding="utf-8"?>
<soap:envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
xmlns:xsd="http://www.w3.org/2001/xmlschema">
<soap:body><addresponse xmlns="http://tempuri.org/">
<addresult>30</addresult></addresponse>
</soap:body></soap:envelope>

這是調用xml web service的方法后,在網絡上傳輸的實際信息。在更復雜的xml web service中,soap響應可能是一個很大的數據集。例如,當northwind中的表orders中的內容被序列化為xml后,數據可能達到454kb。如果我們創建一個應用通過xml web service來獲取這個數據集,那么soap響應將會包含所有的數據。

為了提高效率,在傳輸之前,我們可以壓縮這些文本內容。我們怎樣才能做到呢?當然是使用soap擴展!

soap 擴展

soap擴展是asp.net的web方法調用的一個攔截機制,它能夠在soap請求或響應被傳輸之前操縱它們。開發者可以寫一段代碼在這些消息序列化之前和之后執行。(soap擴展提供底層的api來實現各種各樣的應用。)

使用soap擴展,當客戶端從xml web service調用一個方法的時候,我們能夠減小soap信息在網絡上傳輸的尺寸。許多時候,soap請求要比soap響應小很多(例如,一個大的數據集),因此在我們的例子中,僅對soap響應進行壓縮。就像你在圖1中所看到的,在服務端,當soap響應被序列化后,它會被壓縮,然后傳輸到網絡上。在客戶端,soap信息反序列化之前,為了使反序列化成功,soap信息會被解壓縮。




圖 1. soap信息在序列化后被壓縮(服務端),在反序列化前被解壓縮(客戶端)

我們也可以壓縮soap請求,但在這個例子中,這樣做的效率增加是不明顯的。

為了壓縮我們的web service的soap響應,我們需要做兩件事情:

· 在服務端序列化soap響應信息后壓縮它。
· 在客戶端反序列化soap信息前解壓縮它。

這個工作將由soap擴展來完成。在下面的段落中,你可以看到所有的客戶端和服務端的代碼。

首先,這里是一個返回大數據集的xml web service:

imports system.web.services
<webservice(namespace := "http://tempuri.org/")> _
public class service1
inherits system.web.services.webservice

<webmethod()> public function getorders() as dataset
dim oledbconnection1 = new system.data.oledb.oledbconnection()
oledbconnection1.connectionstring = "provider=sqloledb.1; _
integrated security=sspi;initial catalog=northwind; _
data source=.;workstation id=t-mnikit;"
dim oledbcommand1 = new system.data.oledb.oledbcommand()
oledbcommand1.connection = oledbconnection1
oledbconnection1.open()
dim oledbdataadapter1 = new system.data.oledb.oledbdataadapter()
oledbdataadapter1.selectcommand = oledbcommand1
oledbcommand1.commandtext = "select * from orders"
dim objsampleset as new dataset()
oledbdataadapter1.fill(objsampleset, "orders")
oledbconnection1.close()
return objsampleset
end function

end class



在客戶端,我們構建了一個windows應用程序來調用上面的xml web service,獲取那個數據集并顯示在datagrid中:

public class form1
inherits system.windows.forms.form
''this function invokes the xml web service, which returns the dataset
''without using compression.
private sub button1_click(byval sender as system.object, _
byval e as system.eventargs) handles button1.click
dim ws as new wstest.service1()
dim test1 as new clstimer()
''start time counting…
test1.starttiming()
''fill datagrid with the dataset
datagrid1.datasource = ws.getorders()
test1.stoptiming()
''stop time counting…
textbox5.text = "total time: " & test1.totaltime.tostring & "msec"
end sub

''this function invokes the xml web service, which returns the dataset
''using compression.
private sub button2_click(byval sender as system.object, _
byval e as system.eventargs) handles button2.click
dim ws as new wstest2.service1()
dim test1 as new clstimer()
''start time counting…
test1.starttiming()
''fill datagrid with dataset
datagrid1.datasource = ws.getorders()
test1.stoptiming()
''stop time counting…
textbox4.text = "total time: " & test1.totaltime.tostring & "msec"
end sub

end class

客戶端調用了兩個不同的xml web services, 僅其中的一個使用了soap壓縮。下面的timer類是用來計算調用時間的:

public class clstimer
'' simple high resolution timer class
''
'' methods:
'' starttiming reset timer and start timing
'' stoptiming stop timer
''
''properties
'' totaltime time in milliseconds
''windows api function declarations
private declare function timegettime lib "winmm" () as long

''local variable declarations
private lngstarttime as integer
private lngtotaltime as integer
private lngcurtime as integer

public readonly property totaltime() as string
get
totaltime = lngtotaltime
end get
end property

public sub starttiming()
lngtotaltime = 0
lngstarttime = timegettime()
end sub

public sub stoptiming()
lngcurtime = timegettime()
lngtotaltime = (lngcurtime - lngstarttime)
end sub
end class

服務端的soap擴展

在服務端,為了減小soap響應的尺寸,它被壓縮。下面這段告訴你怎么做:

第一步

使用microsoft visual studio .net, 我們創建一個新的visual basic .net 類庫項目(使用"serversoapextension"作為項目名稱),添加下面的類:

imports system
imports system.web.services
imports system.web.services.protocols
imports system.io
imports zipper

public class myextension
inherits soapextension
private networkstream as stream
private newstream as stream

public overloads overrides function getinitializer(byval _
methodinfo as logicalmethodinfo, _
byval attribute as soapextensionattribute) as object
return system.dbnull.value
end function

public overloads overrides function getinitializer(byval _
webservicetype as type) as object
return system.dbnull.value
end function

public overrides sub initialize(byval initializer as object)
end sub

public overrides sub processmessage(byval message as soapmessage)
select case message.stage

case soapmessagestage.beforeserialize

case soapmessagestage.afterserialize
afterserialize(message)

case soapmessagestage.beforedeserialize
beforedeserialize(message)

case soapmessagestage.afterdeserialize

case else
throw new exception("invalid stage")
end select
end sub

'' save the stream representing the soap request or soap response into a
'' local memory buffer.
public overrides function chainstream(byval stream as stream) as stream
networkstream = stream
newstream = new memorystream()
return newstream
end function

'' write the compressed soap message out to a file at
''the server''s file system..
public sub afterserialize(byval message as soapmessage)
newstream.position = 0
dim fs as new filestream("c:/temp/server_soap.txt", _
filemode.append, fileaccess.write)
dim w as new streamwriter(fs)
w.writeline("-----response at " + datetime.now.tostring())
w.flush()
''compress stream and save it to a file
comp(newstream, fs)
w.close()
newstream.position = 0
''compress stream and send it to the wire
comp(newstream, networkstream)
end sub

'' write the soap request message out to a file at the server''s file system.
public sub beforedeserialize(byval message as soapmessage)
copy(networkstream, newstream)
dim fs as new filestream("c:/temp/server_soap.txt", _
filemode.create, fileaccess.write)
dim w as new streamwriter(fs)
w.writeline("----- request at " + datetime.now.tostring())
w.flush()
newstream.position = 0
copy(newstream, fs)
w.close()
newstream.position = 0
end sub

sub copy(byval fromstream as stream, byval tostream as stream)
dim reader as new streamreader(fromstream)
dim writer as new streamwriter(tostream)
writer.writeline(reader.readtoend())
writer.flush()
end sub

sub comp(byval fromstream as stream, byval tostream as stream)
dim reader as new streamreader(fromstream)
dim writer as new streamwriter(tostream)
dim test1 as string
dim test2 as string
test1 = reader.readtoend
''string compression using nziplib
test2 = zipper.class1.compress(test1)
writer.writeline(test2)
writer.flush()
end sub

end class

'' create a soapextensionattribute for the soap extension that can be
'' applied to an xml web service method.
<attributeusage(attributetargets.method)> _
public class myextensionattribute
inherits soapextensionattribute

public overrides readonly property extensiontype() as type
get
return gettype(myextension)
end get
end property

public overrides property priority() as integer
get
return 1
end get
set(byval value as integer)
end set
end property

end class



第二步

我們增加serversoapextension.dll程序集作為引用,并且在web.config聲明soap擴展:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

<system.web>
<webservices>
<soapextensiontypes>
<add type="serversoapextension.myextension,
serversoapextension" priority="1" group="0"/>
</soapextensiontypes>
</webservices>

...
</system.web>
</configuration>

就象你在代碼中看到的那樣,我們使用了一個臨時目錄("c:/temp")來捕獲soap請求和壓縮過的soap響應到文本文件("c:/temp/server_soap.txt")中 。

客戶端的soap擴展

在客戶端,從服務器來的soap響應被解壓縮,這樣就可以獲取原始的響應內容。下面就一步一步告訴你怎么做:

第一步

使用visual studio .net, 我們創建一個新的visual basic .net類庫項目(使用 "clientsoapextension"作為項目名稱),并且添加下面的類:

imports system
imports system.web.services
imports system.web.services.protocols
imports system.io
imports zipper
public class myextension
inherits soapextension

private networkstream as stream
private newstream as stream

public overloads overrides function getinitializer(byval _
methodinfo as logicalmethodinfo, _
byval attribute as soapextensionattribute) as object
return system.dbnull.value
end function

public overloads overrides function getinitializer(byval _
webservicetype as type) as object
return system.dbnull.value
end function

public overrides sub initialize(byval initializer as object)
end sub

public overrides sub processmessage(byval message as soapmessage)
select case message.stage

case soapmessagestage.beforeserialize

case soapmessagestage.afterserialize
afterserialize(message)

case soapmessagestage.beforedeserialize
beforedeserialize(message)

case soapmessagestage.afterdeserialize

case else
throw new exception("invalid stage")
end select
end sub

'' save the stream representing the soap request or soap response
'' into a local memory buffer.
public overrides function chainstream(byval stream as stream) _
as stream
networkstream = stream
newstream = new memorystream()
return newstream
end function

'' write the soap request message out to a file at
'' the client''s file system.
public sub afterserialize(byval message as soapmessage)
newstream.position = 0
dim fs as new filestream("c:/temp/client_soap.txt", _
filemode.create, fileaccess.write)
dim w as new streamwriter(fs)
w.writeline("----- request at " + datetime.now.tostring())
w.flush()
copy(newstream, fs)
w.close()
newstream.position = 0
copy(newstream, networkstream)
end sub

'' write the uncompressed soap message out to a file
'' at the client''s file system..
public sub beforedeserialize(byval message as soapmessage)
''decompress the stream from the wire
decomp(networkstream, newstream)
dim fs as new filestream("c:/temp/client_soap.txt", _
filemode.append, fileaccess.write)
dim w as new streamwriter(fs)
w.writeline("-----response at " + datetime.now.tostring())
w.flush()
newstream.position = 0
''store the uncompressed stream to a file
copy(newstream, fs)
w.close()
newstream.position = 0
end sub

sub copy(byval fromstream as stream, byval tostream as stream)
dim reader as new streamreader(fromstream)
dim writer as new streamwriter(tostream)
writer.writeline(reader.readtoend())
writer.flush()
end sub

sub decomp(byval fromstream as stream, byval tostream as stream)
dim reader as new streamreader(fromstream)
dim writer as new streamwriter(tostream)
dim test1 as string
dim test2 as string
test1 = reader.readtoend
''string decompression using nziplib
test2 = zipper.class1.decompress(test1)
writer.writeline(test2)
writer.flush()
end sub

end class

'' create a soapextensionattribute for the soap extension that can be
'' applied to an xml web service method.
<attributeusage(attributetargets.method)> _
public class myextensionattribute
inherits soapextensionattribute

public overrides readonly property extensiontype() as type
get
return gettype(myextension)
end get
end property

public overrides property priority() as integer
get
return 1
end get
set(byval value as integer)
end set
end property

end class

就象你在代碼中看到的那樣,我們使用了一個臨時目錄("c:/temp") 來捕獲soap請求和解壓縮的soap響應到文本文件("c:/temp/client_soap.txt")中。

第二步

我們添加clientsoapextension.dll程序集作為引用,并且在我們的應用程序的xml web service引用中聲明soap擴展:

''-------------------------------------------------------------------------
'' <autogenerated>
'' this code was generated by a tool.
'' runtime version: 1.0.3705.209
''
'' changes to this file may cause incorrect behavior and will be lost if
'' the code is regenerated.
'' </autogenerated>
''-------------------------------------------------------------------------
option strict off
option explicit on

imports system
imports system.componentmodel
imports system.diagnostics
imports system.web.services
imports system.web.services.protocols
imports system.xml.serialization

''
''this source code was auto-generated by microsoft.vsdesigner,
''version 1.0.3705.209.
''
namespace wstest2

''<remarks/>
<system.diagnostics.debuggerstepthroughattribute(), _
system.componentmodel.designercategoryattribute("code"), _
system.web.services.webservicebindingattribute(name:="service1soap", _
[namespace]:="http://tempuri.org/")> _
public class service1
inherits system.web.services.protocols.soaphttpclientprotocol

''<remarks/>
public sub new()
mybase.new
me.url = "http://localhost/compressionws/service1.asmx"
end sub

''<remarks/>
<system.web.services.protocols.soapdocumentmethodattribute _
("http://tempuri.org/getproducts",requestnamespace:= _
"http://tempuri.org/", responsenamespace:="http://tempuri.org/", _
use:=system.web.services.description.soapbindinguse.literal,_
parameterstyle:=system.web.services.protocols.soapparameterstyle _
.wrapped), clientsoapextension.myextensionattribute()> _
public function getproducts() as system.data.dataset
dim results() as object = me.invoke("getproducts", _
new object(-1) {})
return ctype(results(0), system.data.dataset)
end function

''<remarks/>
public function begingetproducts(byval callback as _
system.asynccallback, byval asyncstate as object) as system.iasyncresult _

return me.begininvoke("getproducts", new object(-1) {}, _
callback, asyncstate)
end function

''<remarks/>
public function endgetproducts(byval asyncresult as _
system.iasyncresult) as system.data.dataset
dim results() as object = me.endinvoke(asyncresult)
return ctype(results(0), system.data.dataset)
end function
end class
end namespace



這里是zipper類的源代碼,它是使用免費軟件nziplib庫實現的:

using system;
using nzlib.gzip;
using nzlib.compression;
using nzlib.streams;
using system.io;
using system.net;
using system.runtime.serialization;
using system.xml;
namespace zipper
{
public class class1
{
public static string compress(string uncompressedstring)
{
byte[] bytdata = system.text.encoding.utf8.getbytes(uncompressedstring);
memorystream ms = new memorystream();
stream s = new deflateroutputstream(ms);
s.write(bytdata, 0, bytdata.length);
s.close();
byte[] compresseddata = (byte[])ms.toarray();
return system.convert.tobase64string(compresseddata, 0, _
compresseddata.length);
}

public static string decompress(string compressedstring)
{
string uncompressedstring="";
int totallength = 0;
byte[] bytinput = system.convert.frombase64string(compressedstring);;
byte[] writedata = new byte[4096];
stream s2 = new inflaterinputstream(new memorystream(bytinput));
while (true)
{
int size = s2.read(writedata, 0, writedata.length);
if (size > 0)
{
totallength += size;
uncompressedstring+=system.text.encoding.utf8.getstring(writedata, _
0, size);
}
else
{
break;
}
}
s2.close();
return uncompressedstring;
}
}
}



分析

軟件&硬件

· 客戶方: intel pentium iii 500 mhz, 512 mb ram, windows xp.
· 服務器方: intel pentium iii 500 mhz, 512 mb ram, windows 2000 server, microsoft sql server 2000.

在客戶端,一個windows應用程序調用一個xml web service。這個xml web service 返回一個數據集并且填充客戶端應用程序中的datagrid。



圖2. 這是一個我們通過使用和不使用soap壓縮調用相同的xml web service的樣例程序。這個xml web service返回一個大的數據集。

cpu 使用記錄

就象在圖3中顯示的那樣,沒有使用壓縮的cpu使用時間是 29903 milliseconds.



圖 3. 沒有使用壓縮的cpu使用記錄

在我們的例子中,使用壓縮的cpu使用時間顯示在圖4中, 是15182 milliseconds.



圖 4. 使用壓縮的cpu 使用記錄

正如你看到的,我們在客戶方獲取這個數據集的時候,使用壓縮與不使用壓縮少用了近50%的cpu時間,僅僅在cpu加載時有一點影響。當客戶端和服務端交換大的數據時,soap壓縮能顯著地增加xml web services效率。 在web中,有許多改善效率的解決方案。我們的代碼是獲取最大成果但是最便宜的解決方案。soap擴展是通過壓縮交換數據來改善xml web services性能的,這僅僅對cpu加載時間造成了一點點影響。并且值得提醒的是,大家可以使用更強大的和需要更小資源的壓縮算法來獲取更大的效果
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久亚洲精品一区二区| 中文字幕一区电影| 一区二区三区www| 最好看的2019年中文视频| 日韩一区二区三区xxxx| 国产日韩av高清| 日韩中文字幕国产精品| 午夜精品免费视频| 欧美精品一二区| 国产视频亚洲精品| 国精产品一区一区三区有限在线| 国内精品中文字幕| 色先锋资源久久综合5566| 国产一区二区精品丝袜| 高清欧美电影在线| 日韩av在线影院| 国产亚洲欧美日韩一区二区| 亚洲欧美国产精品va在线观看| 国产精品影院在线观看| 一区二区在线视频| 超碰97人人做人人爱少妇| 欧美另类极品videosbestfree| 国产精品99久久久久久久久久久久| 这里只有精品在线播放| 亚洲精品少妇网址| 欧美日韩性视频| 综合欧美国产视频二区| 国产精品入口免费视频一| 亚洲国产精品999| 国产成人精品日本亚洲专区61| 久久久久久久久爱| 亚洲第一福利网| 日韩毛片在线观看| 96sao精品视频在线观看| 欧美日韩亚洲一区二区三区| 亚洲韩国青草视频| 亚洲精品资源在线| 日韩中文字幕av| 成人在线中文字幕| 久久夜色精品国产亚洲aⅴ| 国产在线精品播放| 国产精品福利小视频| 国产激情视频一区| 日韩电影中文字幕在线| 久久精品福利视频| 国产精品久久一| 欧美日韩美女在线| 一区二区三区亚洲| 国产精品久久久久影院日本| 国产精品一区二区三区久久| 亚洲电影第1页| 亚洲第一区中文字幕| 国产成人精品网站| 国产精品成人久久久久| 日韩精品免费综合视频在线播放| 国产精品久久久久福利| 亚洲缚视频在线观看| 日本19禁啪啪免费观看www| 国产日韩欧美影视| 日本久久久久久| 欧美一区二区三区艳史| 97精品视频在线播放| 国产色婷婷国产综合在线理论片a| 国产综合在线视频| 色视频www在线播放国产成人| 久久久中文字幕| 日韩精品视频免费| 亚洲精品美女视频| 欧美专区第一页| x99av成人免费| 精品福利一区二区| 亚洲成av人影院在线观看| 国产精品国内视频| 国产精品人人做人人爽| 亚洲欧洲日产国产网站| 久久成人精品一区二区三区| 亚洲第一精品久久忘忧草社区| 亚洲国产精品视频在线观看| 久久精品国产欧美亚洲人人爽| 欧美视频在线观看免费| 亚洲视频精品在线| 色yeye香蕉凹凸一区二区av| 中文字幕久热精品在线视频| 69av在线视频| 97视频国产在线| 久久av.com| 国产精品一区电影| 亚洲第一视频网站| 欧美在线一区二区三区四| 日本精品久久中文字幕佐佐木| 久久久精品2019中文字幕神马| 韩国19禁主播vip福利视频| 亚洲自拍偷拍视频| 国产精品综合不卡av| 国产男人精品视频| 国产精品视频永久免费播放| 国产精品96久久久久久又黄又硬| 亚洲国模精品一区| 欧美日韩一区免费| 日韩极品精品视频免费观看| 日韩在线免费高清视频| 国产精品成人在线| 亚洲精品视频网上网址在线观看| 精品久久久久久亚洲精品| 97久久精品人搡人人玩| 97精品在线视频| 精品久久久久人成| 久久亚洲国产精品成人av秋霞| 国产精品av电影| 欧美做受高潮1| 高清欧美一区二区三区| 日韩在线视频一区| 亚洲偷熟乱区亚洲香蕉av| 国产成人福利网站| 日本一区二区在线播放| 亚洲色图激情小说| 欧美黑人又粗大| 亚洲影院色无极综合| 日韩专区中文字幕| 久久人人爽人人爽人人片av高清| 亚洲成人精品久久久| 国精产品一区一区三区有限在线| 日本精品视频网站| 久久国产精品网站| 中文字幕日韩欧美精品在线观看| 欧美理论电影网| 黑人巨大精品欧美一区二区三区| 国产精品一区=区| 国产精品网站入口| 九九热在线精品视频| 亚洲欧洲国产精品| 北条麻妃一区二区三区中文字幕| www国产精品视频| 亚洲美女黄色片| 亚洲国产日韩欧美在线99| 国产精品久久久久久久久免费看| 欧美激情第三页| 国产日韩亚洲欧美| 亚洲国产成人在线播放| 国产在线观看不卡| 性欧美暴力猛交69hd| 亚洲美女在线视频| 亚洲日本成人女熟在线观看| 亚洲免费伊人电影在线观看av| 国产日韩亚洲欧美| 97视频在线观看播放| 亚洲资源在线看| 日韩精品视频在线| 欧美性猛交xxx| 国产视频久久久久久久| 992tv成人免费影院| 欧美一级高清免费| 国产精品精品一区二区三区午夜版| 亚洲自拍欧美另类| 欧美亚洲伦理www| 91香蕉亚洲精品| 国产精品综合不卡av| 亚洲字幕在线观看| 国产精品久久久久91| 国产精品白丝jk喷水视频一区| 欧美国产中文字幕| 成人综合国产精品| 91高潮在线观看| 色综合久久天天综线观看|