青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Fork me on GitHub
隨筆 - 215  文章 - 13  trackbacks - 0
<2016年3月>
282912345
6789101112
13141516171819
20212223242526
272829303112
3456789


專注即時(shí)通訊及網(wǎng)游服務(wù)端編程
------------------------------------
Openresty 官方模塊
Openresty 標(biāo)準(zhǔn)模塊(Opm)
Openresty 三方模塊
------------------------------------
本博收藏大部分文章為轉(zhuǎn)載,并在文章開頭給出了原文出處,如有再轉(zhuǎn),敬請(qǐng)保留相關(guān)信息,這是大家對(duì)原創(chuàng)作者勞動(dòng)成果的自覺尊重??!如為您帶來不便,請(qǐng)于本博下留言,謝謝配合。

常用鏈接

留言簿(1)

隨筆分類

隨筆檔案

相冊(cè)

Awesome

Blog

Book

GitHub

Link

搜索

  •  

積分與排名

  • 積分 - 219947
  • 排名 - 118

最新評(píng)論

閱讀排行榜

http://www.infoq.com/cn/articles/game-server-development-2

在上一篇文章中, 我們介紹了游戲服務(wù)器的基本架構(gòu)、相關(guān)框架和Node.js開發(fā)游戲服務(wù)器的優(yōu)勢(shì)。本文我們將通過聊天服務(wù)器的設(shè)計(jì)與開發(fā),來更深入地理解pomelo開發(fā)應(yīng)用的基本流程、開發(fā)思路與相關(guān)的概念。本文并不是開發(fā)聊天服務(wù)器的tutorial,如果需要tutorial和源碼可以看文章最后的參考資料。

為什么是聊天服務(wù)器?

我們目標(biāo)是搭建游戲服務(wù)器,為什么從聊天開始呢?

聊天可認(rèn)為是簡(jiǎn)化的實(shí)時(shí)游戲,它與游戲服務(wù)器有著很多共通之處,如實(shí)時(shí)性、頻道、廣播等。由于游戲在場(chǎng)景管理、客戶端動(dòng)畫等方面有一定的復(fù)雜性,并不適合作為pomelo的入門應(yīng)用。聊天應(yīng)用通常是Node.js入門接觸的第一個(gè)應(yīng)用,因此更適合做入門教程。

Pomelo是游戲服務(wù)器框架,本質(zhì)上也是高實(shí)時(shí)、可擴(kuò)展、多進(jìn)程的應(yīng)用框架。除了在library中有一部分游戲?qū)S玫膸?,其余部分框架完全可用于開發(fā)高實(shí)時(shí)web應(yīng)用。而且與現(xiàn)在有的Node.js高實(shí)時(shí)應(yīng)用框架如derby、socketstream、meteor等比起來有更好的可伸縮性。

相關(guān)贊助商

QCon北京2016大會(huì),4月21-23日,北京·國(guó)際會(huì)議中心,精彩內(nèi)容邀您參與!

對(duì)于大多數(shù)開發(fā)者而言,Node.js的入門應(yīng)用都是一個(gè)基于socket.io開發(fā)的普通聊天室, 由于它是基于單進(jìn)程的Node.js開發(fā)的, 在可擴(kuò)展性上打了一定折扣。例如要擴(kuò)展到類似irc那樣的多頻道聊天室, 頻道數(shù)量的增多必然會(huì)導(dǎo)致單進(jìn)程的Node.js支撐不住。

而基于pomelo框架開發(fā)的聊天應(yīng)用天生就是多進(jìn)程的,可以非常容易地?cái)U(kuò)展服務(wù)器類型和數(shù)量。

從單進(jìn)程到多進(jìn)程,從socket.io到pomelo

一個(gè)基于socket.io的原生聊天室應(yīng)用架構(gòu), 以uberchat為例。

它的應(yīng)用架構(gòu)如下圖所示:

服務(wù)端由單個(gè)Node.js進(jìn)程組成的chat server來接收websocket請(qǐng)求。

它有以下缺點(diǎn):

  1. 可擴(kuò)展性差:只支持單進(jìn)程的Node.js, 無法根據(jù)room/channel分區(qū), 也無法將廣播的壓力與處理邏輯的壓力分開。

  2. 代碼量大:基于socket.io做了簡(jiǎn)單封裝,服務(wù)端就寫了約430行代碼。

用pomelo來寫這個(gè)框架可完全克服以上缺點(diǎn),并且代碼量只要區(qū)區(qū)100多行。

我們要搭建的pomelo聊天室具有如下的運(yùn)行架構(gòu):

在這個(gè)架構(gòu)里, 前端服務(wù)器也就是connector專門負(fù)責(zé)承載連接, 后端的聊天服務(wù)器則是處理具體邏輯的地方。 這樣擴(kuò)展的運(yùn)行架構(gòu)具有如下優(yōu)勢(shì): * 負(fù)載分離:這種架構(gòu)將承載連接的邏輯與后端的業(yè)務(wù)處理邏輯完全分離,這樣做是非常必要的, 尤其是廣播密集型應(yīng)用(例如游戲和聊天)。密集的廣播與網(wǎng)絡(luò)通訊會(huì)占掉大量的資源,經(jīng)過分離后業(yè)務(wù)邏輯的處理能力就不再受廣播的影響。

  • 切換簡(jiǎn)便:因?yàn)橛辛饲?、后端兩層的架?gòu),用戶可以任意切換頻道或房間都不需要重連前端的websocket。

  • 擴(kuò)展性好:用戶數(shù)的擴(kuò)展可以通過增加connector進(jìn)程的數(shù)量來支撐。頻道的擴(kuò)展可以通過哈希等算法負(fù)載均衡到多臺(tái)聊天服務(wù)器上。理論上這個(gè)架構(gòu)可以實(shí)現(xiàn)頻道和用戶的無限擴(kuò)展。

聊天服務(wù)器開發(fā)架構(gòu)

game server與web server

聊天服務(wù)器項(xiàng)目中分生成了game-server目錄、web-server目錄與shared目錄,如下圖所示:

這樣也將應(yīng)用天然地隔離成了兩個(gè),game server與web server。

  • Game server, 即游戲服務(wù)器,所有的游戲服務(wù)器邏輯都在里實(shí)現(xiàn)??蛻舳送ㄟ^websocket(0.3版會(huì)支持tcp的socket)連到game server。game-server/app.js是游戲服務(wù)器的運(yùn)行入口。
  • Web server,即web服務(wù)器, 也可以認(rèn)為是游戲服務(wù)器的一個(gè)web客戶端, 所有客戶端的js代碼,web端的html、css資源都存放在這里,web服務(wù)端的用戶登錄、認(rèn)證等功能也在這里實(shí)現(xiàn)。pomelo也提供了其它客戶端,包括ios、android、unity3D等。
  • Shared目錄,假如客戶端是web,由于服務(wù)端和客戶端都是javascript寫的,這時(shí)Node.js的代碼重用優(yōu)勢(shì)就體現(xiàn)出來了。shared目錄下可以存放客戶端、服務(wù)端共用的常量、算法。真正做到一遍代碼, 前后端共用。

服務(wù)器定義與應(yīng)用目錄

Game server才是游戲服務(wù)器的真正入口,游戲邏輯都在里, 我們簡(jiǎn)單看一下game-server的目錄結(jié)構(gòu),如下圖所示:

servers目錄下所有子目錄定義了各種類型的服務(wù)器,而每個(gè)servers目錄下基本都包含了handler和remote兩個(gè)目錄。 這是pomelo的創(chuàng)新之處,用極簡(jiǎn)的配置實(shí)現(xiàn)游戲服務(wù)器的定義,后文會(huì)解釋handler和remote。

通過pomelo,游戲開發(fā)者可以自由地定義自己的服務(wù)器類型,分配和管理進(jìn)程資源。在pomelo中,根據(jù)服務(wù)器的職責(zé)不同,服務(wù)器主要分為前端服務(wù)器(frontend)和后端服務(wù)器(backend)兩大類。其中,前端服務(wù)器負(fù)責(zé)承載客戶端的連接和維護(hù)session信息,所有服務(wù)器與客戶端的消息都會(huì)經(jīng)過前端服務(wù)器;后端服務(wù)器負(fù)責(zé)接收前端服務(wù)器分發(fā)過來的請(qǐng)求,實(shí)現(xiàn)具體的游戲邏輯,并把消息回推給前端服務(wù)器,最后發(fā)送給客戶端。如下圖所示:

動(dòng)態(tài)語言的面向?qū)ο笥袀€(gè)基本概念叫鴨子類型。在pomelo中,服務(wù)器的抽象也同樣可以比喻為鴨子,服務(wù)器的對(duì)外接口只有兩類, 一類是接收客戶端的請(qǐng)求, 叫做handler, 一類是接收RPC請(qǐng)求, 叫做remote, handler和remote的行為決定了服務(wù)器長(zhǎng)什么樣子。 因此開發(fā)者只需要定義好handler和remote兩類的行為, 就可以確定這個(gè)服務(wù)器的類型。 例如chat服務(wù)器目前的行為只有兩類,分別是定義在handler目錄中的chatHandler.js,和定義在remote目錄中的chatRemote.js。只要定義好這兩個(gè)類的方法,聊天服務(wù)器的對(duì)外接口就確定了。

搭建聊天服務(wù)器

準(zhǔn)備知識(shí)

pomelo的客戶端服務(wù)器通訊

pomelo的客戶端和服務(wù)器之間的通訊可以分為三種:

  • request-response

    pomelo中最常用的就是request-response模式,客戶端發(fā)送請(qǐng)求,服務(wù)器異步響應(yīng)??蛻舳说恼?qǐng)求發(fā)送形式類似ajax類似:

    ``` pomelo.request(url, msg, function(data){}); ``` 

    第一個(gè)參數(shù)為請(qǐng)求地址,完整的請(qǐng)求地址主要包括三個(gè)部分:服務(wù)器類型、服務(wù)端相應(yīng)的文件名及對(duì)應(yīng)的方法名。第二個(gè)參數(shù)是消息體,消息體為json格式,第三個(gè)參數(shù)是回調(diào)函數(shù),請(qǐng)求的響應(yīng)將會(huì)把結(jié)果置入這個(gè)回調(diào)函數(shù)中返回給客戶端。

  • notify

    notify與request—response類似,唯一區(qū)別是客戶端只負(fù)責(zé)發(fā)送消息到服務(wù)器,客戶端不接收服務(wù)器的消息響應(yīng)。

    ``` pomelo.notify(url, msg); ``` 
  • push

    push則是服務(wù)器主動(dòng)向客戶端進(jìn)行消息推送,客戶端根據(jù)路由信息進(jìn)行消息區(qū)分,轉(zhuǎn)發(fā)到后。通常游戲服務(wù)器都會(huì)發(fā)送大量的這類廣播。

    ``` pomelo.on(route, function(data){}); ``` 

以上是javascript的api, 其它客戶端的API基本與這個(gè)類型。由于API與ajax極其類似,所有web應(yīng)用的開發(fā)者對(duì)此都不陌生。

session介紹

與web服務(wù)器類似,session是游戲服務(wù)器存放用戶會(huì)話的抽象。但與web不同,游戲服務(wù)器的session是基于長(zhǎng)連接的, 一旦建立就一直保持。這反而比web中的session更直接,也更簡(jiǎn)單。 由于長(zhǎng)連接的session不會(huì)web應(yīng)用一樣由于連接斷開重連帶來session復(fù)制之類的問題,簡(jiǎn)單地將session保存在前端服務(wù)器的內(nèi)存中是明智的選擇。

在pomelo中session也是key/value對(duì)象,其主要作用是維護(hù)當(dāng)前用戶信息,例如:用戶的id,所連接的前端服務(wù)器id等。session由前端服務(wù)器維護(hù),前端服務(wù)器在分發(fā)請(qǐng)求給后端服務(wù)器時(shí),會(huì)復(fù)制session并連同請(qǐng)求一起發(fā)送。任何直接在session上的修改,只對(duì)本服務(wù)器進(jìn)程生效,并不會(huì)影響到用戶的全局狀態(tài)信息。如需修改全局session里的狀態(tài)信息,需要調(diào)用前端服務(wù)器提供的RPC服務(wù)。

channel與廣播

廣播在游戲中是極其重要的,幾乎大部分的消息都需要通過廣播推送到客戶端,再由客戶端播放接收的消息。而channel則是服務(wù)器端向客戶端進(jìn)行消息廣播的通道。 可以把channel看成一個(gè)用戶id的容器.把用戶id加入到channel中成為當(dāng)中的一個(gè)成員,之后向channel推送消息,則該channel中所有的成員都會(huì)收到消息。channel只適用于服務(wù)器進(jìn)程本地,即在服務(wù)器進(jìn)程A創(chuàng)建的channel和在服務(wù)器進(jìn)程B創(chuàng)建的channel是兩個(gè)不同的channel,相互不影響。

服務(wù)器之間RPC通訊

從之前的文章可以了解到,在pomelo中,游戲服務(wù)器其實(shí)是一個(gè)多進(jìn)程相互協(xié)作的環(huán)境。各個(gè)進(jìn)程之間通信,主要是通過底層統(tǒng)一的RPC框架來實(shí)現(xiàn),服務(wù)器間的RPC調(diào)用也實(shí)現(xiàn)了零配置。具體RPC調(diào)用的代碼如下:

```javascript app.rpc.chat.chatRemote.add(session, uid, app.get ('serverId'), function(data){}); ``` 

其中app是pomelo的應(yīng)用對(duì)象,app.rpc表明了是前后臺(tái)服務(wù)器的Remote rpc調(diào)用,后面的參數(shù)分別代表服務(wù)器的名稱、對(duì)應(yīng)的文件名稱及方法名。為了實(shí)現(xiàn)這個(gè)rpc調(diào)用,則只需要在對(duì)應(yīng)的chat/remote/中新建文件chatRemote.js,并實(shí)現(xiàn)add方法。

聊天室流程概述

下圖列出了聊天室進(jìn)行聊天的完整流程:

通過以上流程, 我們可以看到pomelo的基本請(qǐng)求流程和用法。本文不是聊天室的tutorial,因此下面列出的代碼不是完整的,而是用極簡(jiǎn)的代碼來說明pomelo的使用流程和api。

進(jìn)入聊天室

客戶端向前端服務(wù)器發(fā)起登錄請(qǐng)求:

```javascript     pomelo.request('connector.entryHandler.enter',      {user:userInfo}, function(){}); ``` 

用戶進(jìn)入聊天室后,服務(wù)器端首先需要完成用戶的session注冊(cè)同時(shí)綁定用戶離開事件:

```javascript session.bind(uid); session.on('closed', onUserLeave.bind(null, app)); ``` 

另外,服務(wù)器端需要通過調(diào)用rpc方法將用戶加入到相應(yīng)的channel中;同時(shí)在rpc方法中,服務(wù)器端需要將該用戶的上線消息廣播給其他用戶,最后服務(wù)器端向客戶端返回當(dāng)前channel中的用戶列表信息。

```javascript app.rpc.chat.chatRemote.add(session, uid,  serverId,function(){}); ``` 

發(fā)起聊天

客戶端向服務(wù)端發(fā)起聊天請(qǐng)求,請(qǐng)求消息包括聊天內(nèi)容,發(fā)送者和發(fā)送目標(biāo)信息。消息的接收者可以聊天室里所有的用戶,也可以是某一特定用戶。

服務(wù)器端根據(jù)客戶端的發(fā)送的請(qǐng)求,進(jìn)行不同形式的消息廣播。如果發(fā)送目標(biāo)是所有用戶,服務(wù)器端首先會(huì)選擇channel中的所有用戶,然后向channel發(fā)送消息,最后前端服務(wù)器就會(huì)將消息分別發(fā)送給channel中取到的用戶;如果發(fā)送目標(biāo)只是某一特定用戶,發(fā)送過程和之前完全一樣,只是服務(wù)器端首先從channel中選擇的只是一個(gè)用戶,而不是所有用戶。

```javascript     if(msg.target == '*')          channel.pushMessage(param);     else         channelService.pushMessageByUids(param,         [{uid:uid, sid:sid}]); ``` 

接收聊天消息

客戶端接收廣播消息,并將消息并顯示即可。

```javascript     pomelo.on('onChat', function() {         addMessage(data.from, data.target, data.msg);             $("#chatHistory").show();     }); ``` 

退出聊天室

用戶在退出聊天室時(shí),必須完成一些清理工作。在session斷開連接時(shí),通過rpc調(diào)用將用戶從channel中移除。在用戶退出前,還需要將自己下線的消息廣播給所有其他用戶。

```javascript     app.rpc.chat.chatRemote.kick(session, uid, serverId,      channelName, null); ``` 

聊天服務(wù)器的可伸縮性與擴(kuò)展討論

上一講已經(jīng)談到pomelo在提供了一個(gè)高可伸縮性的運(yùn)行架構(gòu),對(duì)于聊天服務(wù)器同樣如此。如果想從單頻道聊天室擴(kuò)展到多頻道聊天室,增加的代碼幾乎為零。大部分工作只是在進(jìn)行服務(wù)器和路由的配置。對(duì)于服務(wù)器配置只需要修改json配置文件即可,而對(duì)于路由配置只需要增加一個(gè)路由算法即可。在pomelo中,開發(fā)者可以自己配置客戶端到服務(wù)器的路由規(guī)則,這樣會(huì)使得游戲開發(fā)更加靈活。

我們來看一下配置json文件對(duì)服務(wù)器運(yùn)行架構(gòu)的影響:

  • 最簡(jiǎn)服務(wù)器與運(yùn)行架構(gòu):

  • 擴(kuò)展后的服務(wù)器與運(yùn)行架構(gòu):

另外,在0.3版本的pomelo中增加了動(dòng)態(tài)增刪服務(wù)器的功能,開發(fā)者可以在不停服務(wù)的情況下根據(jù)當(dāng)前應(yīng)用運(yùn)行的負(fù)載情況添加新的服務(wù)器或者停止閑置的服務(wù)器,這樣可以讓服務(wù)器資源得到更充分的利用。

總結(jié)

本文通過聊天服務(wù)器的搭建過程,分析了pomelo開發(fā)應(yīng)用的基本流程,基本架構(gòu)與相關(guān)概念。有了這些知識(shí)我們可以輕松地使用pomelo搭建高實(shí)時(shí)應(yīng)用了。 在后文中我們將分析更復(fù)雜的游戲案例,并且會(huì)對(duì)架構(gòu)中的一些實(shí)現(xiàn)深入剖析。

相關(guān)資源:

posted on 2016-03-14 09:13 思月行云 閱讀(1810) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Node.js
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲在线一区二区| 国产一区视频网站| 中文在线资源观看网站视频免费不卡 | 欧美亚洲一区在线| 国产日韩欧美不卡| 久久九九久精品国产免费直播| 午夜久久久久| 亚洲国产精品成人综合| 亚洲成色777777女色窝| 欧美jjzz| 亚洲香蕉伊综合在人在线视看| 夜夜嗨网站十八久久| 国产精品成人av性教育| 美脚丝袜一区二区三区在线观看| 欧美自拍偷拍| 日韩午夜三级在线| 亚洲一区日韩| 国产一区二区三区在线观看精品| 免播放器亚洲| 欧美日韩视频在线第一区| 亚洲欧美另类中文字幕| 久久国产高清| 亚洲调教视频在线观看| 欧美一区三区三区高中清蜜桃| 亚洲大片在线观看| 宅男噜噜噜66一区二区| 国内精品美女在线观看| 亚洲精品日韩综合观看成人91| 国产精品美女一区二区| 欧美激情性爽国产精品17p| 国产精品免费aⅴ片在线观看| 裸体一区二区三区| 欧美午夜精品久久久久久浪潮 | 亚洲一区二区三区色| 欧美一区二区三区视频在线| 亚洲精品影视| 久久久精品网| 欧美一区二区成人6969| 欧美日韩大片| 欧美大片一区二区三区| 国产精品制服诱惑| 亚洲欧洲日夜超级视频| 国产午夜精品久久久久久久| 亚洲精品欧美激情| 在线观看亚洲视频| 亚洲欧美在线看| 亚洲性视频h| 欧美aⅴ一区二区三区视频| 久久国产精品黑丝| 国产精品久久77777| 亚洲人成啪啪网站| 亚洲国产日韩一区| 久久久噜噜噜久久人人看| 亚洲欧美日韩天堂| 欧美性大战久久久久久久| 亚洲激情欧美| 亚洲人线精品午夜| 嫩草国产精品入口| 欧美电影免费观看高清| 好看不卡的中文字幕| 亚洲一区视频在线| 亚洲资源在线观看| 国产精品视频区| 在线中文字幕不卡| 亚洲综合色激情五月| 欧美伦理91| 亚洲精品视频免费观看| 一本一本久久a久久精品综合麻豆| 玖玖玖国产精品| 欧美大片免费观看在线观看网站推荐| 国产一区二区三区精品欧美日韩一区二区三区| 亚洲视频狠狠| 午夜日本精品| 国产一区二区中文字幕免费看| 亚洲欧美视频一区二区三区| 欧美一区免费视频| 国产一区二区久久精品| 欧美专区日韩专区| 麻豆精品一区二区av白丝在线| 久久精品国产亚洲精品| 一区在线播放| 欧美+亚洲+精品+三区| 亚洲国产精品v| 99精品视频网| 国产欧美日韩一区二区三区| 久久aⅴ国产紧身牛仔裤| 欧美成人tv| 一本色道久久综合亚洲精品不卡| 欧美视频在线播放| 欧美一区日韩一区| 亚洲国产专区| 欧美一区视频在线| 在线观看一区二区视频| 欧美性开放视频| 久久久国产一区二区| 亚洲韩国精品一区| 欧美一二三区精品| 亚洲第一伊人| 欧美日韩国产首页在线观看| 一区二区三区精品视频| 欧美一区二区三区视频| 禁断一区二区三区在线 | 亚洲国产精品久久久| 免费观看亚洲视频大全| 99在线热播精品免费| 香蕉久久国产| 在线精品视频一区二区| 欧美国产精品日韩| 一区二区欧美国产| 久久久国产精品一区| 亚洲国产成人av好男人在线观看| 欧美黄网免费在线观看| 亚洲网址在线| 蜜臀久久99精品久久久久久9 | 亚洲精品视频在线观看网站| 国产精品a久久久久| 久久久精品一区| 一本色道久久88精品综合| 久久久久国产一区二区| 99在线|亚洲一区二区| 国产午夜精品在线| 欧美视频一区在线| 久久综合综合久久综合| 中日韩高清电影网| 欧美成人69av| 久久精彩免费视频| 在线观看日韩专区| 韩日欧美一区二区| 国产精品久久91| 欧美 日韩 国产一区二区在线视频| 一区二区三区国产在线| 欧美激情麻豆| 欧美伊人精品成人久久综合97| 中文网丁香综合网| 亚洲人体1000| 伊人激情综合| 国产精品一区二区三区免费观看| 欧美波霸影院| 欧美一级专区| 欧美一区二区三区四区视频| 亚洲毛片视频| 亚洲高清在线播放| 久久阴道视频| 亚洲尤物视频在线| 午夜精彩国产免费不卡不顿大片| 亚洲国产日韩一级| 1024欧美极品| 久久亚洲午夜电影| 亚洲国产合集| 亚洲国产精品传媒在线观看| 欧美成人a∨高清免费观看| 亚洲图片欧美午夜| 亚洲午夜精品网| 中文久久乱码一区二区| 亚洲免费观看| 亚洲精品久久久久久久久久久久久| 国产精品日韩久久久| 国产日韩欧美自拍| 国产日韩欧美综合一区| 国产精品一二三四| 国产精品一区二区在线观看| 欧美日韩亚洲国产一区| 欧美亚州韩日在线看免费版国语版| 欧美激情视频网站| 欧美第一黄网免费网站| 欧美精品久久一区二区| 欧美精品成人一区二区在线观看| 久久狠狠婷婷| 欧美大片一区二区| 欧美日韩成人网| 欧美午夜精彩| 国产亚洲精品资源在线26u| 欧美亚一区二区| 在线观看欧美日本| 亚洲精品久久久一区二区三区| 亚洲激情精品| 一区二区三区高清不卡| 亚洲一区欧美激情| 久热这里只精品99re8久| 亚洲成色www久久网站| 亚洲精品1区2区| 在线中文字幕日韩| 亚洲一区二区三区欧美| 免费成人高清在线视频| 欧美日韩一区三区| 国产精品一二三四区| 在线观看欧美日本| 亚洲在线观看免费| 久久婷婷人人澡人人喊人人爽| 美女视频黄免费的久久| 亚洲精品影视在线观看| 日韩一区二区免费高清| 久久久久久久久蜜桃| 欧美日韩大片一区二区三区| 国产亚洲精品aa午夜观看| 91久久精品www人人做人人爽| 日韩一级精品视频在线观看| 麻豆成人精品| 一本久久a久久精品亚洲| 久久亚洲国产精品日日av夜夜|