Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 欧美激情成人,亚洲第一免费网站,一级在线|欧洲

          整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          稅友股份取得數(shù)據(jù)交互方法專利,HTML程序可確保擺脫HTTP服務(wù)的束縛,以使HTML能夠更好地在本地程序中進(jìn)行應(yīng)用

          融界2024年7月9日消息,天眼查知識產(chǎn)權(quán)信息顯示,稅友軟件集團(tuán)股份有限公司取得一項(xiàng)名為“一種數(shù)據(jù)交互方法、系統(tǒng)、電子設(shè)備及存儲(chǔ)介質(zhì)“,授權(quán)公告號CN113010237B,申請日期為2021年3月。

          專利摘要顯示,本發(fā)明公開了一種數(shù)據(jù)交互方法,包括:HTML程序利用HTML容器提供的服務(wù)接口生成本地資源獲取請求,并通過HTML容器的容器進(jìn)程將本地資源獲取請求發(fā)送至本地服務(wù)容器;本地服務(wù)容器利用本地服務(wù)容器中包含的業(yè)務(wù)服務(wù)對接收到的本地資源獲取請求進(jìn)行處理,得到相應(yīng)的本地資源數(shù)據(jù),并將本地資源數(shù)據(jù)發(fā)送至HTML容器;HTML容器接收本地資源數(shù)據(jù),并將本地資源數(shù)據(jù)發(fā)送至HTML程序;本方法中的HTML程序可直接使用HTML容器及本地服務(wù)容器進(jìn)行本地資源獲取,可確保HTML程序擺脫HTTP服務(wù)的束縛,以使HTML能夠更好地在本地程序中進(jìn)行應(yīng)用;本發(fā)明還提供數(shù)據(jù)交互系統(tǒng)、電子設(shè)備及存儲(chǔ)介質(zhì),具有上述有益效果。

          本文源自金融界

          擊右上方,關(guān)注開源中國OSC頭條號,獲取最新技術(shù)資訊

          學(xué)習(xí) Netty 也有一段時(shí)間了,為了更好的掌握 Netty,我手動(dòng)造了個(gè)輪子,一個(gè)基于 Netty 的 web 框架:redant,中文叫紅火蟻。創(chuàng)建這個(gè)項(xiàng)目的目的主要是學(xué)習(xí)使用 Netty,俗話說不要輕易的造輪子,但是通過造輪子我們可以學(xué)到很多優(yōu)秀開源框架的設(shè)計(jì)思路,編寫優(yōu)美的代碼,更好的提升自己。

          PS:項(xiàng)目地址:https://github.com/all4you/redant

          快速啟動(dòng)

          Redant 是一個(gè)基于 Netty 的 Web 容器,類似 Tomcat 和 WebLogic 等容器

          只需要啟動(dòng)一個(gè) Server,默認(rèn)的實(shí)現(xiàn)類是 NettyHttpServer 就能快速啟動(dòng)一個(gè) web 容器了,如下所示:

          public final class ServerBootstrap {
           public static void main(String[] args) {
           Server nettyServer = new NettyHttpServer();
           // 各種初始化工作
           nettyServer.preStart();
           // 啟動(dòng)服務(wù)器
           nettyServer.start();
           }
          }
          

          我們可以直接啟動(dòng) redant-example 模塊中的 ServerBootstrap 類,因?yàn)?redant-example 中有很多示例的 Controller,我們直接運(yùn)行 example 中的 ServerBootstrap,啟動(dòng)后你會(huì)看到如下的日志信息:

          在 redant-example 模塊中,內(nèi)置了以下幾個(gè)默認(rèn)的路由:

          啟動(dòng)成功后,可以訪問 http://127.0.0.1:8888/ 查看效果,如下圖所示:

          如果你可以看到 "Welcome to redant!" 這樣的消息,那就說明你啟動(dòng)成功了。

          自定義路由

          框架實(shí)現(xiàn)了自定義路由,通過 @Controller @Mapping 注解就可以唯一確定一個(gè)自定義路由。如下列的 UserController 所示:

          和 Spring 的使用方式一樣,訪問 /user/list 來看下效果,如下圖所示:

          結(jié)果渲染

          目前支持 json、html、xml、text 等類型的結(jié)果渲染,用戶只需要在 方法的 @Mapping 注解上通過 renderType 來指定具體的渲染類型即可,如果不指定的話,默認(rèn)以 json 類型范圍。

          如下圖所示,首頁就是通過指定 renderType 為 html 來返回一個(gè) html 頁面的:

          IOC容器

          從 UserController 的代碼中,我們看到 userServerce 對象是通過 @Autowired 注解自動(dòng)注入的,這個(gè)功能是任何一個(gè) IOC 容器基本的能力,下面我們來看看如何實(shí)現(xiàn)一個(gè)簡單的 IOC 容器。

          首先定義一個(gè) BeanContext 接口,如下所示:

          public interface BeanContext {
           /**
           * 獲得Bean
           * @param name Bean的名稱
           * @return Bean
           */
           Object getBean(String name);
           /**
           * 獲得Bean
           * @param name Bean的名稱
           * @param clazz Bean的類
           * @param <T> 泛型
           * @return Bean
           */
           <T> T getBean(String name,Class<T> clazz);
          }
          

          然后我們需要在系統(tǒng)啟動(dòng)的時(shí)候,掃描出所有被 @Bean 注解修飾的類,然后對這些類進(jìn)行實(shí)例化,然后把實(shí)例化后的對象保存在一個(gè) Map 中即可,如下圖所示:

          代碼很簡單,通過在指定路徑下掃描出所有的類之后,把實(shí)例對象加入map中,但是對于已經(jīng)加入的 bean 不能繼續(xù)加入了,加入之后要獲取一個(gè) Bean 也很簡單了,直接通過 name 到 map 中去獲取就可以了。

          現(xiàn)在我們已經(jīng)把所有 @Bean 的對象管理起來了,那對于依賴到的其他的 bean 該如何注入呢,換句話說就是將我們實(shí)例化好的對象賦值給 @Autowired 注解修飾的變量。

          簡單點(diǎn)的做法就是遍歷 beanMap,然后對每個(gè) bean 進(jìn)行檢查,看這個(gè) bean 里面的每個(gè) setter 方法和屬性,如果有 @Autowired 注解,那就找到具體的 bean 實(shí)例之后將值塞進(jìn)去。

          setter注入

          field注入

          通過Aware獲取BeanContext

          BeanContext 已經(jīng)實(shí)現(xiàn)了,那怎么獲取 BeanContext 的實(shí)例呢?想到 Spring 中有很多的 Aware 接口,每種接口負(fù)責(zé)一種實(shí)例的回調(diào),比如我們想要獲取一個(gè) BeanFactory 那只要將我們的類實(shí)現(xiàn) BeanFactoryAware 接口就可以了,接口中的 setBeanFactory(BeanFactory factory) 方法參數(shù)中的 BeanFactory 實(shí)例就是我們所需要的,我們只要實(shí)現(xiàn)該方法,然后將參數(shù)中的實(shí)例保存在我們的類中,后續(xù)就可以直接使用了。

          那現(xiàn)在我就來實(shí)現(xiàn)這樣的功能,首先定義一個(gè) Aware 接口,所有其他需要回調(diào)塞值的接口都繼承自該接口,如下所示:

          public interface Aware {
          }
          public interface BeanContextAware extends Aware{
           /**
           * 設(shè)置BeanContext
           * @param beanContext BeanContext對象
           */
           void setBeanContext(BeanContext beanContext);
          }
          

          接下來需要將 BeanContext 的實(shí)例注入到所有 BeanContextAware 的實(shí)現(xiàn)類中去。BeanContext 的實(shí)例很好得到,BeanContext 的實(shí)現(xiàn)類本身就是一個(gè) BeanContext 的實(shí)例,并且可以將該實(shí)例設(shè)置為單例,這樣的話所有需要獲取 BeanContext 的地方都可以獲取到同一個(gè)實(shí)例。

          拿到 BeanContext 的實(shí)例后,我們就需要掃描出所有實(shí)現(xiàn)了 BeanContextAware 接口的類,并實(shí)例化這些類,然后調(diào)用這些類的 setBeanContext 方法,參數(shù)就傳我們拿到的 BeanContext 實(shí)例。

          邏輯理清楚之后,實(shí)現(xiàn)起來就很簡單了,如下圖所示:

          Cookie管理

          基本上所有的 web 容器都會(huì)有 cookie 管理的能力,那我們的 redant 也不能落后。首先定義一個(gè) CookieManager 的接口,核心的操作 cookie 的方法如下:

          public interface CookieManager {
           Set<Cookie> getCookies();
           Cookie getCookie(String name);
           
           void addCookie(String name,String value);
           void setCookie(Cookie cookie);
           boolean deleteCookie(String name);
          }
          

          其中我只列舉了幾個(gè)核心的方法,另外有一些不同參數(shù)的重載方法,這里就不詳細(xì)介紹了。最關(guān)鍵的是兩個(gè)方法,一個(gè)是讀 Cookie 一個(gè)是寫 Cookie 。

          讀 Cookie

          Netty 中是通過 HttpRequest 的 Header 來保存請求中所攜帶的 Cookie的,所以要讀取 Cookie 的話,最關(guān)鍵的是獲取到 HttpRequest。而 HttpRequest 可以在 ChannelHandler 中拿到,通過 HttpServerCodec 進(jìn)行編解碼,Netty 已經(jīng)幫我們把請求的數(shù)據(jù)轉(zhuǎn)換成 HttpRequest 了。但是這個(gè) HttpRequest 只在 ChannelHandler 中才能訪問到,而處理 Cookie 通常是用戶自定義的操作,并且對用戶來說他是不關(guān)心 HttpRequest 的,他只需要通過 CookieManager 去獲取一個(gè) Cookie 就行了。

          這種情況下,最適合的就是將 HttpRequest 對象保存在一個(gè) ThreadLocal 中,在 CookieManager 中需要獲取的時(shí)候,直接到 ThreadLocal 中去取出來就可以了,如下列代碼所示:

          @Override
          public Set<Cookie> getCookies() {
           HttpRequest request = TemporaryDataHolder.loadHttpRequest();
           Set<Cookie> cookies = new HashSet<>();
           if(request != null) {
           String value = request.headers().get(HttpHeaderNames.COOKIE);
           if (value != null) {
           cookies = ServerCookieDecoder.STRICT.decode(value);
           }
           }
           return cookies;
          }
          

          TemporaryDataHolder 就是那個(gè)通過 ThreadLocal 保存了 HttpRequest 的類。

          寫 Cookie

          寫 Cookie 和讀 Cookie 面臨著一樣的問題,就是寫的時(shí)候需要借助于 HttpResponse,將 Cookie 寫入 HttpResponse 的 Header 中去,但是用戶執(zhí)行寫 Cookie 操作的時(shí)候,根本就不關(guān)心 HttpResponse,甚至他在寫的時(shí)候,還沒有 HttpResponse。

          這時(shí)的做法也是將需要寫到 HttpResponse 中的 Cookie 保存在 ThreadLocal 中,然后在最后通過 channel 寫響應(yīng)之前,將 Cookie 拿出來塞到 HttpResponse 中去即可,如下列代碼所示:

          @Override
          public void setCookie(Cookie cookie) {
           TemporaryDataHolder.storeCookie(cookie);
          }
          /**
           * 響應(yīng)消息
           */
          private void writeResponse(){
           boolean close = isClose();
           response.headers().add(HttpHeaderNames.CONTENT_LENGTH, String.valueOf(response.content().readableBytes()));
           // 從ThreadLocal中取出待寫入的cookie
           Set<Cookie> cookies = TemporaryDataHolder.loadCookies();
           if(!CollectionUtil.isEmpty(cookies)){
           for(Cookie cookie : cookies){
           // 將cookie寫入response中
           response.headers().add(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.STRICT.encode(cookie));
           }
           }
           ChannelFuture future = channel.write(response);
           if(close){
           future.addListener(ChannelFutureListener.CLOSE);
           }
          }
          

          攔截器

          攔截器是一個(gè)框架很重要的功能,通過攔截器可以實(shí)現(xiàn)一些通用的工作,比如登錄鑒權(quán),事務(wù)處理等等。記得在 Servlet 的年代,攔截器是非常重要的一個(gè)功能,基本上每個(gè)系統(tǒng)都會(huì)在 web.xml 中配置很多的攔截器。

          攔截器的基本思想是,通過一連串的類去執(zhí)行某個(gè)攔截的操作,一旦某個(gè)類中的攔截操作返回了 false,那就終止后面的所有流程,直接返回。

          這種場景非常適合用責(zé)任鏈模式去實(shí)現(xiàn),而 Netty 的 pipeline 本身就是一個(gè)責(zé)任鏈模式的應(yīng)用,所以我們就可以通過 pipeline 來實(shí)現(xiàn)我們的攔截器。這里我定義了兩種類型的攔截器:前置攔截器和后置攔截器。

          前置攔截器是在處理用戶的業(yè)務(wù)邏輯之前的一個(gè)攔截操作,如果該操作返回了 false 則直接 return,不會(huì)繼續(xù)執(zhí)行用戶的業(yè)務(wù)邏輯。

          后置攔截器就有點(diǎn)不同了,后置攔截器主要就是處理一些后續(xù)的操作,因?yàn)楹笾脭r截器再跟前置攔截器一樣,當(dāng)操作返回了 false 直接 return 的話,已經(jīng)沒有意義了,因?yàn)闃I(yè)務(wù)邏輯已經(jīng)執(zhí)行完了。

          理解清楚了具體的邏輯之后,實(shí)現(xiàn)起來就很簡單了,如下列代碼所示:

          前置攔截器

          后置攔截器

          有了實(shí)現(xiàn)之后,我們需要把他們加到 pipeline 中合適的位置,讓他們在整個(gè)責(zé)任鏈中生效,如下圖所示:

          指定攔截器的執(zhí)行順序

          目前攔截器還沒有實(shí)現(xiàn)指定順序執(zhí)行的功能,其實(shí)也很簡單,可以定義一個(gè) @InterceptorOrder 的注解應(yīng)用在所有的攔截器的實(shí)現(xiàn)類上,掃描到攔截器的結(jié)果之后,根據(jù)該注解進(jìn)行排序,然后把拍完序之后的結(jié)果添加到 pipeline 中即可。

          集群模式

          到目前為止,我描述的都是單節(jié)點(diǎn)模式,如果哪一天單節(jié)點(diǎn)的性能無法滿足了,那就需要使用集群了,所以我也實(shí)現(xiàn)了集群模式。

          集群模式是由一個(gè)主節(jié)點(diǎn)和若干個(gè)從節(jié)點(diǎn)構(gòu)成的。主節(jié)點(diǎn)接收到請求后,將請求轉(zhuǎn)發(fā)給從節(jié)點(diǎn)來處理,從節(jié)點(diǎn)把處理好的結(jié)果返回給主節(jié)點(diǎn),由主節(jié)點(diǎn)把結(jié)果響應(yīng)給請求。

          要想實(shí)現(xiàn)集群模式需要有一個(gè)服務(wù)注冊和發(fā)現(xiàn)的功能,目前是借助于 Zk 來做的服務(wù)注冊與發(fā)現(xiàn)。

          準(zhǔn)備一個(gè) Zk 服務(wù)端

          因?yàn)橹鞴?jié)點(diǎn)需要把請求轉(zhuǎn)發(fā)給從節(jié)點(diǎn),所以主節(jié)點(diǎn)需要知道目前有哪些從節(jié)點(diǎn),我通過 ZooKeeper 來實(shí)現(xiàn)服務(wù)注冊與發(fā)現(xiàn)。

          如果你沒有可用的 Zk 服務(wù)端的話,那你可以通過運(yùn)行下面的 Main 方法來啟動(dòng)一個(gè) ZooKeeper 服務(wù)端:

          public final class ZkBootstrap {
           private static final Logger LOGGER = LoggerFactory.getLogger(ZkBootstrap.class);
           public static void main(String[] args) {
           try {
           ZkServer zkServer = new ZkServer();
           zkServer.startStandalone(ZkConfig.DEFAULT);
           }catch (Exception e){
           LOGGER.error("ZkBootstrap start failed,cause:",e);
           System.exit(1);
           }
           }
          }
          

          這樣你就可以在后面啟動(dòng)主從節(jié)點(diǎn)的時(shí)候使用這個(gè) Zk 了。但是這并不是必須的,如果你已經(jīng)有一個(gè)正在運(yùn)行的 Zk 的服務(wù)端,那么你可以在啟動(dòng)主從節(jié)點(diǎn)的時(shí)候直接使用它,通過在 main 方法的參數(shù)中指定 Zk 的地址即可。

          啟動(dòng)主節(jié)點(diǎn)

          只需要運(yùn)行下面的代碼,就可以啟動(dòng)一個(gè)主節(jié)點(diǎn)了:

          public class MasterServerBootstrap {
           public static void main(String[] args) {
           String zkAddress = ZkServer.getZkAddressArgs(args,ZkConfig.DEFAULT);
           // 啟動(dòng)MasterServer
           Server masterServer = new MasterServer(zkAddress);
           masterServer.preStart();
           masterServer.start();
           }
          }
          

          如果在 main 方法的參數(shù)中指定了 Zk 的地址,就通過該地址去進(jìn)行服務(wù)發(fā)現(xiàn),否則會(huì)使用默認(rèn)的 Zk 地址。

          啟動(dòng)從節(jié)點(diǎn)

          只需要運(yùn)行下面的代碼,就可以啟動(dòng)一個(gè)從節(jié)點(diǎn)了:

          public class SlaveServerBootstrap {
           public static void main(String[] args) {
           String zkAddress = ZkServer.getZkAddressArgs(args,ZkConfig.DEFAULT);
           Node node = Node.getNodeWithArgs(args);
           // 啟動(dòng)SlaveServer
           Server slaveServer = new SlaveServer(zkAddress,node);
           slaveServer.preStart();
           slaveServer.start();
           }
          }
          

          如果在 main 方法的參數(shù)中指定了 Zk 的地址,就通過該地址去進(jìn)行服務(wù)注冊,否則會(huì)使用默認(rèn)的 Zk 地址。

          實(shí)際上多節(jié)點(diǎn)模式具體的處理邏輯還是復(fù)用了單節(jié)點(diǎn)模式的核心功能,只是把原本一臺(tái)實(shí)例擴(kuò)展到多臺(tái)實(shí)例而已。

          總結(jié)

          本文通過介紹一個(gè)基于 Netty 的 web 容器,讓我們了解了一個(gè) http 服務(wù)端的大概的構(gòu)成,當(dāng)然實(shí)現(xiàn)中可能有更加好的方法。但是主要的還是要了解內(nèi)在的思想,包括 Netty 的一些基本的使用方法。

          我會(huì)繼續(xù)優(yōu)化該項(xiàng)目,加入更多的特性,例如服務(wù)發(fā)現(xiàn)與注冊當(dāng)前是通過 Zk 來實(shí)現(xiàn)的,未來可能會(huì)引入其他的組件去實(shí)現(xiàn)服務(wù)注冊與發(fā)現(xiàn)。

          除此之外,Session 的管理還未完全實(shí)現(xiàn),后續(xù)也需要對這一塊進(jìn)行完善。

          博客作者:逅弈

          每日一博欄目,每日為你推薦優(yōu)秀博主的優(yōu)質(zhì)技術(shù)文章。同時(shí)歡迎用戶投稿,文章一旦被官方賬號收錄,我們會(huì)在網(wǎng)站首頁等位置進(jìn)行推薦哦。關(guān)注開源中國OSC每日獲取優(yōu)質(zhì)推送,點(diǎn)擊“了解更多”閱讀原文章。

          ↓↓↓

          SS容器查詢終于來了! 它們目前在谷歌瀏覽器(105)中得到了支持,很快就會(huì)在Safari 16中得到支持。這對前端來說容器查詢與媒體查詢一樣重要。

          在這節(jié)課中,我們介紹一下容器查詢是如何工作的,如何使用它們,以及語法是什么樣子的,并分享一些現(xiàn)實(shí)生活中的例子和用例。

          簡介

          在設(shè)計(jì)一個(gè)組件時(shí),我們需要適配不同的變化,并根據(jù)CSS類或視口大小來改變它們。這對于我們開發(fā)來說不是很理想,會(huì)迫使我們根據(jù)變化類或視口尺寸來寫CSS。

          考慮下面例子:

          我們有一個(gè)卡片組件,當(dāng)視口足夠大時(shí),它應(yīng)該切換到水平樣式。乍一看,這可能聽起來不錯(cuò)。然而,當(dāng)你更深入地思考這個(gè)問題時(shí),它就有點(diǎn)復(fù)雜了。

          如果我們想在不同的地方使用同一個(gè)卡片組件,比如在空間狹小的側(cè)邊欄和有更多空間的主區(qū)域,我們就需要使用不同的類來適配:

          .c-article {
            /* Default stacked style */
          }
          
          @media (min-width: 800px) {
            /* Horizontal style. */
            .c-article--horizontal {
              display: flex;
              align-items: center;
            }
          }
          

          如果我們不想用上面的方式,那么會(huì)出現(xiàn)下面這樣的情況:

          這種從用戶界面的角度來看,并不友好。

          通過容器查詢,我們可以簡單地編寫響應(yīng)父級或容器寬度的CSS。請看下圖:

          注意到在媒體查詢中,我們是如何根據(jù)視口或屏幕寬度來查詢一個(gè)組件的。在容器查詢中,同樣的情況發(fā)生在父級上。

          什么是容器查詢?

          通過 container-type 屬性查詢一個(gè)組件與最接近的父類的關(guān)系,該父類有一個(gè)定義的包含物。

          我們過去在媒體查詢中寫CSS的方式,但只是針對組件層面。

          容器查詢語法

          要根據(jù)一個(gè)組件的父級寬度查詢,我們需要使用 container-type 屬性。看下面的例子"

          .wrapper {
            container-type: inline-size;
          }
          

          有了這些,我們就可以開始查詢一個(gè)組件。在下面的例子中,如果.card元素的容器的寬度等于400px或更大,我們需要添加一個(gè)特定的樣式。

          @container (min-width: 400px) {
            .card {
              display: flex;
              align-items: center;
            }
          }
          

          雖然上述方法可行,但當(dāng)有多個(gè)容器時(shí),就會(huì)造成混亂。為了避免這種情況,最好為一個(gè)容器命名。

          .wrapper {
            container-type: inline-size;
            container-name: card;
          }
          

          現(xiàn)在,我們可以在 @container 旁邊加容器名稱,如下所示。

          @container card (min-width: 400px) {
            .card {
              display: flex;
              align-items: center;
            }
          }
          

          完整代碼:

          .wrapper {
            container-type: inline-size;
            container-name: card;
          }
          
          .c-article {
            /* Default stacked style */
          }
          
          @container card (min-width: 400px) {
            /* Horizontal style. */
            .c-article {
              display: flex;
              align-items: center;
            }
          }
          

          瀏覽器支持

          容器查詢現(xiàn)在在Chrome 105中得到支持,并很快在Safari 16中得到支持。

          事例

          這邊有10個(gè)關(guān)于容器查詢的事例,地址:https://lab.ishadeed.com/container-queries

          來源:https://ishadeed.com/article/container-queries-are-finally-here/


          主站蜘蛛池模板: 国产在线观看一区二区三区精品 | 亚洲天堂一区二区三区| 久久久91精品国产一区二区三区| 久久精品免费一区二区喷潮| 3d动漫精品啪啪一区二区免费| 国产熟女一区二区三区四区五区 | 亚洲国产日韩一区高清在线| 鲁丝丝国产一区二区| 日本无卡码一区二区三区| 久久久综合亚洲色一区二区三区| 蜜桃视频一区二区| 日韩免费无码一区二区视频| 国产大秀视频在线一区二区| 日本亚洲成高清一区二区三区| 国产在线精品一区二区夜色| 国产精品一区电影| 国产伦理一区二区三区| 日本一区二区三区精品视频| 春暖花开亚洲性无区一区二区| 亚洲熟妇无码一区二区三区| 亚洲A∨精品一区二区三区下载| 免费无码一区二区三区| 91久久精品一区二区| 在线播放国产一区二区三区 | 亚洲AV无码一区二三区| 国产情侣一区二区三区| 中文字幕Av一区乱码| 久久福利一区二区| 无码国产精品一区二区免费虚拟VR | 人妻精品无码一区二区三区| 国产福利电影一区二区三区久久久久成人精品综合 | 中文无码AV一区二区三区| 一区二区三区无码高清| 国产无吗一区二区三区在线欢| 无码人妻精品一区二区蜜桃AV| 精品一区二区三区高清免费观看 | 国产精品亚洲专区一区| 一区二区三区在线视频播放| 亚洲av综合av一区| 无码中文字幕人妻在线一区二区三区 | 中文字幕无码免费久久9一区9|