国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院

首頁 > 開發 > 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加載時間造成了一點點影響。并且值得提醒的是,大家可以使用更強大的和需要更小資源的壓縮算法來獲取更大的效果
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院
国产区视频在线| 天堂资源在线中文| 国产女王在线**视频 | 最近最好的中文字幕2019免费| 国产成人精品久久一区二区小说| 国产日本视频| 精品成人免费自拍视频| 国产精品久久久久白浆| 精灵使的剑舞无删减版在线观看| 亚洲最新永久观看在线| 国产原创在线播放| 亚洲欧美小说国产图片| 国产一级激情| 九九热在线观看视频| 精品一区二区91| 久久久久久久久久久久久91| 国产福利视频在线观看| 国内精品不卡| www操操操| 国产无套粉嫩白浆在线2022年| 国产麻豆一区二区三区精品| 精品推荐蜜桃传媒| 在线观看午夜av| 中文字幕在线观看日本| 青青国产在线| 天天操夜夜添| av高清资源| 精品入口麻豆传煤| 2021av在线| 国产成+人+亚洲+欧美+综合| 午夜在线小视频| 国产在线高潮| 天天操天天操一操| 最近中文字幕mv免费高清在线| www.狠狠操.com| 久久综合第一页| 黄色片免费在线| аⅴ成人天堂中文在线| 国产激情99| 国产精品入口麻豆完整版| 国产秒拍福利视频露脸| 免费a级在线播放| 超碰在线网址| 国产蜜臀在线| 国产小视频在线| 国产精品区一区二| 国产黄色av免费看| 中文在线视频观看| 在线激情小视频| 久热国产在线视频| 中文字幕网在线| 精品推荐国产麻豆剧传媒| 国产鲁鲁视频在线观看特色| 国产毛片毛片毛片| 国产福利微拍精品一区二区| 国产黄色免费电影| jizz一区二区三区| 国产精品作爱| 在线中文视频| 狠狠操五月天| 国产色视频网站| gogo高清在线播放免费| 国产在线中文字幕| 国产欧美日韩第一页| 国产www.大片在线| eeuss影院在线| 国产精品剧情一区二区在线观看 | 日本免费黄色| 国产探花在线观看| www操操操| 国产精品人人爱一区二区白浆| 亚洲综合色视频在线观看| 国产专区在线| 一本大道香蕉久久| 尤物视频在线免费观看| 精品福利影院| 中文字幕中文字幕在线中高清免费版 | 成年黄网站在线观看免费| 久久亚洲国产成人亚| 精品一区二区三区在线成人 | 国产一卡二卡3卡4卡四卡在线| 在线视频婷婷| 午夜视频在线看| 国自产拍在线网站网址视频| 亚洲综合天堂网| 国产日产精品久久久久久婷婷| 欧美日韩国产亚洲沙发| 91社区在线观看| 国产精品麻豆一区二区三区 | 久热免费视频| 国产黄色高清在线| 国产一卡二卡3卡4卡四卡在线| www.91在线播放| eeuss影院在线| 亚洲天堂电影在线观看| 国产jizz| 在线激情网站| 亚洲人成电影| 精品国产一区二区三区久久久狼牙 | 久久综合精品视频| 麻豆国产在线播放| 日本免费黄色| 超碰国产在线观看| 本道综合精品| 黄色片视频在线观看| www在线观看播放免费视频日本| 91青青在线视频| 在线观看中文| 欧美视频免费一区二区三区 | 精品176二区| 精品女厕厕露p撒尿| 精品极品三级久久久久| av人人综合网| 国产精选在线观看| 国产系列电影在线播放网址| 国产激情99| 色综合久久五月天| 好吊日视频在线观看| 国产网红在线观看| 夜夜操天天干| 中文字幕国产欧美| 在线免费黄色毛片| 中文字幕视频在线免费| 在线免费黄色毛片| 成年午夜在线| 99在线视频影院| 国产美女一区视频| 亚洲国产日韩在线人成电影| 国内精品不卡| 日本高清中文字幕在线| 综合激情亚洲| 日本在线观看| 中文字幕高清av| 欧美午夜电影一区二区三区| 国产视频资源| 麻豆国产视频| 亚洲成人在线播放| 国产对白国语对白| 日本中文字幕在线视频| 超碰97国产精品人人cao| 国产精品理人伦一区二区三区 | 国产网红在线| 成人欧美亚洲| 国产永久免费高清在线观看视频| 国产精品美女一区二区视频| 久热免费视频| 一本大道久久精品| 国产对白叫床清晰在线播放| 国产无套粉嫩白浆在线2022年| 九九99九九精彩| 狠狠操五月天| 国产鲁鲁视频在线观看特色| 激情四房婷婷| 国产精品作爱| 国产精品四虎| 国产黄色在线免费观看| 国产精品久久久久白浆| 国产无套粉嫩白浆在线2022年| 1区2区视频| 国产美女av| 国产精品自产拍在线观看2019| 九九在线免费视频| 国产在线一二三| 中文字幕亚洲精品视频| √天堂8资源中文在线| 国产欧美一区二区三区小说| 国产黄色在线免费观看| 尤物视频在线观看视频| 嫩草在线播放| 国产偷窥洗澡视频| 在线观看午夜av| 九九热在线视频| 国产黄在线观看| 日本片在线看| 国产在线观看av| 国产高潮av| 日本不卡1区2区3区| 国产精品亚洲色图| 精品麻豆国产| 久草亚洲一区| 精品卡1卡2卡三卡免费网站| 欧美日韩视频精品二区| 国产深夜视频在线观看| 在线观看免费高清完整| 福利在线视频导航| 在线中文免费视频| 天堂在线中文| 日本韩国精品一区二区| 国产丝袜在线| 99久久99久久免费精品小说| 九九热在线视频| 97视频在线观看网站| 黄污在线观看| 精品全国在线一区二区| 国产在线精品一区二区不卡| 2021av天天| 国产午夜精品久久久久免费视 | 在线a人片免费观看视频| 黄色在线视频观看网站| 在线观看中文字幕|