精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Springboot 整合 Websocket 輕松實(shí)現(xiàn) IM 及時(shí)通訊

開發(fā) 前端
項(xiàng)目中碰到需要及時(shí)通訊的場(chǎng)景,使用Springboot集成Websocket,即可瞬間破局。本文介紹Springboot如何集成Websocket、IM及時(shí)通訊需要哪些模塊、開發(fā)和部署過(guò)程中遇到的問(wèn)題、以及實(shí)現(xiàn)小型IM及時(shí)通訊的代碼。

一、方案實(shí)踐

集成分為三步:添加依賴、增加配置類和消息核心類、前端集成。

1.1、添加依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
    <version>2.1.13.RELEASE</version>
</dependency>

1.2、增加WebSocket配置類

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**
 * WebSocket配置
 */
@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

1.3、增加消息核心類WebSocketServer

@ServerEndpoint("/websocket/{userId}")
@Component
@Slf4j
public class WebSocketServer {
    // 消息存儲(chǔ)
    private static MessageStore messageStore;
    // 消息發(fā)送
    private static MessageSender messageSender;

    public static void setMessageStore(MessageStore messageStore) {
        WebSocketServer.messageStore = messageStore;
    }

    public static void setMessageSender(MessageSender messageSender) {
        WebSocketServer.messageSender = messageSender;
    }

    /**
     * 連接建立成功調(diào)用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        messageStore.saveSession(session);
    }

    /**
     * 連接關(guān)閉調(diào)用的方法
     */
    @OnClose
    public void onClose(Session session, @PathParam("userId") String userId) {
        messageStore.deleteSession(session);
    }

    /**
     * 收到客戶端消息后調(diào)用的方法
     *
     * @ Param message 客戶端發(fā)送過(guò)來(lái)的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) throws Exception {
        log.warn("=========== 收到來(lái)自窗口" + session.getId() + "的信息:" + message);
        handleTextMessage(session, new TextMessage(message));
    }

    /**
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, @PathParam("userId") String userId, Throwable error) {
        log.error("=========== 發(fā)生錯(cuò)誤");
        error.printStackTrace();
//        msgStore.deleteSession(session);
    }

    public void handleTextMessage(Session session, TextMessage message) throws Exception {
        log.warn("=========== Received message: {}", message.getPayload());
    }
}

1.4、前端頁(yè)面加入socket

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/html">
  <head>
    <title>WebSocket Example</title>
  </head>
  <body>
    登錄用戶ID:<input type="text" id="sendUserId" /></br>
    接受用戶ID:<input type="text" id="receivedUserId" /></br>
    發(fā)送消息內(nèi)容:<input type="text" id="messageInput" /></br>
    接受消息內(nèi)容:<input type="text" id="messageReceive" /></br>
    <button onclick="sendMessage()">Send</button>

    <script>
      var socket = new WebSocket("ws://localhost:8080/websocket/aaa");
      var roomId = "123456";
      // 隨機(jī)產(chǎn)出六位數(shù)字
      var sendUserId = Math.floor(Math.random() * 1000000);

      document.getElementById("sendUserId").value = sendUserId;
      var messageReceive = document.getElementById("messageReceive");


      socket.onopen = function (event) {
        console.log("WebSocket is open now.");
        let loginInfo = {
          msgType: 2, //登錄消息
          sendUserId: sendUserId,
          bizType: 1, //業(yè)務(wù)類型
          bizOptModule: 1, //業(yè)務(wù)模塊
          roomId: roomId,
          msgBody: {},
        };
        socket.send(JSON.stringify(loginInfo));
      };

      socket.onmessage = function (event) {
        var message = event.data;
        console.log("Received message: " + message);
        messageReceive.value = message;
      };

      socket.onclose = function (event) {
        console.log("WebSocket is closed now.");
      };

      function sendMessage() {
        var message = document.getElementById("messageInput").value;
        var receivedUserId = document.getElementById("receivedUserId").value;
        let operateInfo = {
          msgType: 100, //業(yè)務(wù)消息
          sendUserId: sendUserId,
          bizType: 1, //業(yè)務(wù)類型
          bizOptModule: 1, //業(yè)務(wù)模塊
          roomId: roomId,
          receivedUserId: receivedUserId,
          msgBody: {
            operateType: 1, //操作類型:禁言
            operateContent: "1",
          },
        };
        socket.send(JSON.stringify(operateInfo));
      }

      setInterval(() => {
        socket.send("ping");
      }, 30000);
    </script>
  </body>
</html>

二、小型及時(shí)通訊包含的模塊

以上只是集成了Websocket框架,實(shí)現(xiàn)了基本的全雙工通信,服務(wù)器和客戶端都可以同時(shí)發(fā)送和接收數(shù)據(jù)。要想實(shí)現(xiàn)一些小型完整的及時(shí)通訊,還需要具備以下幾個(gè)核心模塊。架構(gòu)圖如下:

2.1、架構(gòu)圖

圖片圖片

2.2、消息對(duì)象模型

組織消息內(nèi)容,比如消息類型、發(fā)送者用戶ID、接受者用戶ID、具體的消息體等。比如:

public class SocketMsg<T> {

    /**
     * 消息類型:1心跳  2登錄 3業(yè)務(wù)操作
     */
    private Integer msgType;

    /**
     * 發(fā)送者用戶ID
     */
    private String sendUserId;
    /**
     * 接受者用戶ID
     */
    private String receivedUserId;

    /**
     * 業(yè)務(wù)類型
     */
    private Integer bizType;

    /**
     * 業(yè)務(wù)操作模塊
     */
    private Integer bizOptModule;

    /**
     * 消息內(nèi)容
     */
    private T msgBody;
}

2.3、消息存儲(chǔ)模塊

負(fù)責(zé)存儲(chǔ)消息內(nèi)容、用戶ID和sessionID的關(guān)系,防止數(shù)據(jù)丟失或者服務(wù)器重啟等。

2.4、消息發(fā)送模塊

功能開發(fā)完畢,一般部署到分布式集群環(huán)境,所以通訊時(shí)session會(huì)分布在多臺(tái)服務(wù)器。比如用戶A的session在機(jī)器1,用戶B的session在機(jī)器2,此時(shí)A發(fā)送給B,就無(wú)法單獨(dú)通過(guò)機(jī)器1完成。

因?yàn)闄C(jī)器1拿不到機(jī)器2里的session,所以消息發(fā)不過(guò)去。此時(shí)只能借助別的中間件來(lái)實(shí)現(xiàn),比如借助消息中間件kafka實(shí)現(xiàn)。

機(jī)器1將消息發(fā)送給kafka,然后機(jī)器1和機(jī)器2都監(jiān)聽(tīng)kafka,然后查看用戶對(duì)應(yīng)的session是否在本機(jī),如果在本機(jī)則發(fā)送出去。

2.5、消息推送模塊

模塊3提到的消息發(fā)送流程中,消息發(fā)送給 消息中間件,然后服務(wù)器消費(fèi)到消費(fèi),在通過(guò)本機(jī)的session推送給客戶端。

三、遇到的幾個(gè)問(wèn)題

3.1、連接自動(dòng)斷開

WebSocket連接之后,發(fā)現(xiàn)一個(gè)問(wèn)題:每隔一段時(shí)間如果不傳送數(shù)據(jù)的話,與前端的連接就會(huì)自動(dòng)斷開。可以采用心跳消息的方式來(lái)解決這個(gè)問(wèn)題。比如客服端每隔30秒自動(dòng)發(fā)送ping消息給服務(wù)端,服務(wù)端返回pong。

3.2、Session無(wú)法被序列化

分布式場(chǎng)景會(huì)存在這樣的問(wèn)題:當(dāng)一次請(qǐng)求負(fù)載到第一臺(tái)服務(wù)器時(shí),session在第一臺(tái)服務(wù)器線程上,第二次請(qǐng)求,負(fù)載到第二臺(tái)服務(wù)器上,此時(shí)通過(guò)userId查找當(dāng)前用戶的session時(shí),是查找不到的。

本來(lái)想著把session存入到redis中,就可以從redis獲取用戶的session,希望用這種方式來(lái)解決分布式場(chǎng)景下消息發(fā)送的問(wèn)題。但是會(huì)出現(xiàn)如下錯(cuò)誤:

The remote endpoint was in state [STREAM_WRITING] which is an invalid state for called method

翻看了session源碼,發(fā)現(xiàn)session無(wú)法被序列化。所以這個(gè)方案只能放棄。解決方案請(qǐng)看下面的問(wèn)題5或者上面的架構(gòu)圖。

3.3、對(duì)象無(wú)法自動(dòng)注入

使用了@ServerEndpoint注解的類中使用@Resource或@Autowired注入對(duì)象都會(huì)失敗,并且報(bào)空指針異常。

原因是WebSocket服務(wù)是線程安全的,那么當(dāng)我們?nèi)グl(fā)起一個(gè)ws連接時(shí),就會(huì)創(chuàng)建一個(gè)端點(diǎn)對(duì)象。WebSocket服務(wù)是多對(duì)象的,不是單例的。而我們的Spring的Bean默認(rèn)就是單例的,在非單例類中注入一個(gè)單例的Bean是沖突的。

或者說(shuō):

Spring管理采用單例模式(singleton),而 WebSocket 是多對(duì)象的,即每個(gè)客戶端對(duì)應(yīng)后臺(tái)的一個(gè) WebSocket 對(duì)象,也可以理解成 new 了一個(gè) WebSocket,這樣當(dāng)然是不能獲得自動(dòng)注入的對(duì)象了,因?yàn)檫@兩者剛好沖突。

@Autowired 注解注入對(duì)象操作是在啟動(dòng)時(shí)執(zhí)行的,而不是在使用時(shí),而 WebSocket 是只有連接使用時(shí)才實(shí)例化對(duì)象,且有多個(gè)連接就有多個(gè)對(duì)象。所以我們可以得出結(jié)論,這個(gè) Service 根本就沒(méi)有注入到 WebSocket 當(dāng)中。

如何解決呢?

使用靜態(tài)對(duì)象,并且對(duì)外暴露set方法,這樣在對(duì)象初始化的時(shí)候,將其注入到WebSocketServer中。比如說(shuō)這樣:

@ServerEndpoint("/websocket/{userId}")
@Component
@Slf4j
public class WebSocketServer {
  private static MessageStore messageStore;
  private static MessageSender messageSender;

  public static void setMessageStore(MessageStore messageStore) {
      WebSocketServer.messageStore = messageStore;
  }

  public static void setMessageSender(MessageSender messageSender) {
      WebSocketServer.messageSender = messageSender;
  }
}


@Slf4j
@Service
public class MessageStore {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @PostConstruct
    public void init() {
        WebSocketServer.setMessageStore(this);
    }
}

3.4、分布式場(chǎng)景消息如何發(fā)給客戶端

問(wèn)題2中提到了分布式場(chǎng)景下存在的session不在本機(jī)的問(wèn)題,這種場(chǎng)景可以通過(guò)發(fā)送消息中間件的方式解決。具體這樣解決:

每次連接時(shí),都將userId和對(duì)應(yīng)的session存入到本機(jī),發(fā)送消息時(shí),直接發(fā)送給MQ-Broker,然后每臺(tái)應(yīng)用負(fù)載都去消費(fèi)這個(gè)消息,拿到消息之后,判斷在本機(jī)能根據(jù)userId是否能找到session,找到session則推送到客戶端。

3.5、部署時(shí)Nginx配置問(wèn)題

代碼開發(fā)完畢之后,本機(jī)跑通后,然后部署到服務(wù)器之后,還差很重要的一步:配置nginx代理。

3.5.1、給后端應(yīng)用部署獨(dú)立域名

要給后端應(yīng)用部署獨(dú)立域名,nginx代理直接轉(zhuǎn)發(fā)到應(yīng)用的獨(dú)立域名,不要走微服務(wù)的gateway網(wǎng)關(guān)轉(zhuǎn)發(fā)過(guò)去。

3.5.2、多層nginx轉(zhuǎn)發(fā)問(wèn)題

當(dāng)只有一層nginx的時(shí)候,配置比較簡(jiǎn)單,如下:

location ~* ^/api/websocket/* {
      proxy_pass http://mangodwsstest.mangod.top;
      
      proxy_read_timeout 300s;
      proxy_send_timeout 300s;
      proxy_set_header Host mangodwsstest.mangod.top;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "Upgrade";
      proxy_set_header X-Real-IP $remote_addr;
 }

但是,當(dāng)有兩層nginx轉(zhuǎn)發(fā)的時(shí)候,問(wèn)題就出現(xiàn)了。

在最外層的nginx需要使用如下配置,不能照抄后面一層的配置。proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for和proxy_set_header X-Forwarded-Proto $scheme這兩個(gè)配置不能少,用來(lái)將協(xié)議和真實(shí)IP傳遞給后面一層的nginx。

location ~* ^/api/websocket/* {
      proxy_pass http://mangodwsstest.mangod.top;

      proxy_read_timeout 300s;
      proxy_send_timeout 300s;
      proxy_set_header  Host $http_host;
      proxy_set_header  X-Real-IP  $remote_addr;
      proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header  X-Forwarded-Proto $scheme;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection $connection_upgrade;
}

四、完整代碼和示例

4.1、頁(yè)面效果如下

開啟兩個(gè)web頁(yè)面,用戶1輸入用戶2的用戶ID,輸入發(fā)送消息內(nèi)容,點(diǎn)擊發(fā)送。在用戶2的頁(yè)面的接受消息內(nèi)容可以看到發(fā)送的消息。

圖片圖片

圖片圖片

4.2、代碼結(jié)構(gòu)

圖片圖片

4.3、代碼地址

https://github.com/yclxiao/spring-websocket.git

五、總結(jié)

本文聊了Springboot如何集成Websocket、IM及時(shí)通訊需要哪些模塊、開發(fā)和部署過(guò)程中遇到的問(wèn)題、以及實(shí)現(xiàn)小型IM及時(shí)通訊的代碼。

責(zé)任編輯:武曉燕 來(lái)源: Java極客技術(shù)
相關(guān)推薦

2023-01-13 00:02:41

2023-01-05 09:17:58

2023-08-09 08:01:00

WebSockett服務(wù)器web

2021-03-26 08:16:32

SpringbootWebsocket前端

2012-08-13 13:03:31

Web

2024-09-12 14:50:08

2024-11-14 12:22:37

SpringMail郵件

2015-06-02 11:24:06

容聯(lián)云通訊

2024-11-18 17:04:03

Vue3C#

2023-07-26 07:28:55

WebSocket服務(wù)器方案

2021-03-25 08:29:33

SpringBootWebSocket即時(shí)消息

2023-08-14 08:01:12

websocket8g用戶

2024-03-21 08:34:49

Vue3WebSocketHTTP

2021-08-14 09:23:03

即時(shí)通訊IM互聯(lián)網(wǎng)

2021-02-05 07:28:11

SpringbootNettyWebsocke

2020-04-23 15:08:41

SpringBootMyCatJava

2024-09-05 08:58:37

2022-04-28 07:31:41

Springkafka數(shù)據(jù)量

2024-08-02 09:00:17

NettyWebSocketNIO

2024-08-29 08:58:30

JPA編寫數(shù)據(jù)操
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

三级在线免费观看| 欧美精品成人91久久久久久久| 极品美女扒开粉嫩小泬| 欧美一区二区在线观看视频| 一区二区国产精品| 亚洲天堂免费视频| gai在线观看免费高清| 国产成人高清精品| 成人一级片在线观看| 91地址最新发布| 精品一区二区三区蜜桃在线| 日韩黄色三级| 亚洲国产日产av| 欧美凹凸一区二区三区视频 | 亚洲丝袜美腿综合| 成人看片人aa| 精品视频一区二区在线观看| 综合干狼人综合首页| 欧美日韩国产欧美日美国产精品| 亚洲小视频在线播放| 无码国产伦一区二区三区视频| 视频一区欧美日韩| 欧美高清视频在线播放| 亚洲av综合一区二区| 欧美舌奴丨vk视频| 一区二区三区四区av| 免费试看一区| 国产超碰人人模人人爽人人添| 在线视频免费在线观看一区二区| 中文字幕不卡在线视频极品| 亚洲国产精品狼友在线观看| 精品肉辣文txt下载| 亚洲香肠在线观看| 亚洲午夜精品一区二区三区| 日本高清视频免费观看| 美女mm1313爽爽久久久蜜臀| 国内揄拍国内精品| 亚洲第一综合网| av综合网站| 欧美性猛交xxxxxx富婆| 欧美变态另类刺激| 搞黄网站在线观看| 久久亚洲二区三区| 91免费欧美精品| 国产一级片av| 亚洲视频二区| 欧美激情第一页xxx| 黄色激情小视频| 亚洲自拍电影| 亚洲国产日韩一区| 91av免费观看| 亚洲精品三区| 欧美视频一区在线| 中文字幕无码不卡免费视频| 另类视频在线| 亚洲精品视频一区| 中文字幕免费在线不卡| 啊v在线视频| 国产亚洲va综合人人澡精品| 国产精品sss| 精品人妻一区二区三区日产乱码 | 国产一区亚洲二区三区| 国产夫妻在线| 亚洲自拍偷拍欧美| 97干在线视频| 牛牛电影国产一区二区| 一区二区三区av电影| 九九久久九九久久| av片哪里在线观看| 一区二区三区四区中文字幕| 在线观看18视频网站| 毛片在线看网站| 国产精品灌醉下药二区| 在线看成人av电影| 四虎久久免费| 自拍偷拍国产精品| 妞干网这里只有精品| av福利在线播放| 国产精品欧美精品| 中国一区二区三区| dj大片免费在线观看| 一区二区不卡在线视频 午夜欧美不卡在| 在线播放 亚洲| 美女av在线播放| 亚洲激情自拍视频| 国产va亚洲va在线va| a√中文在线观看| 亚洲国产精品麻豆| 北条麻妃69av| 玛雅亚洲电影| 欧美性三三影院| 中文字幕色网站| 91精品国产自产精品男人的天堂| 亚洲成人1234| 日本黄色特级片| gogogo高清在线观看一区二区| 中文精品99久久国产香蕉| 特级西西人体高清大胆| 一本到12不卡视频在线dvd| 欧美国产精品va在线观看| www.av视频在线观看| 久久精品盗摄| 成人黄色av播放免费| 成人激情四射网| 97久久超碰国产精品电影| 日韩一本精品| 日本大片在线播放| 在线精品国精品国产尤物884a| 男人的天堂最新网址| 林ゆな中文字幕一区二区| 亚洲精品中文字幕女同| 一级免费黄色录像| 精品69视频一区二区三区Q| 国产91在线高潮白浆在线观看| 亚洲最大成人av| 成人动漫精品一区二区| 日韩精品一区二区三区外面| 亚洲国产精品精华素| 日韩欧美中文免费| www.色.com| 妖精视频一区二区三区| 久久久国产成人精品| 亚洲影院在线播放| 国产精品影视在线观看| 日韩激情久久| av成人 com a| 3d成人动漫网站| 人妻大战黑人白浆狂泄| 欧美日韩一区二区国产| 国产精品久久精品| 日韩专区第一页| 1024成人网色www| 午夜精品久久久内射近拍高清| 九九99久久精品在免费线bt| 影音先锋欧美精品| 国产成人免费看| 国产成人三级在线观看| 一本一生久久a久久精品综合蜜| 欧产日产国产精品视频| 日韩亚洲欧美成人一区| youjizz亚洲女人| 亚洲永久在线| 成人一区二区在线| gogo在线高清视频| 欧美日韩国产成人在线免费| 亚洲天堂视频一区| 国产精品五区| 精品国产一区二区三| 三级资源在线| 91精品久久久久久久91蜜桃| 影音先锋男人在线| 丝袜国产日韩另类美女| 精品日产一区2区三区黄免费 | 国产激情视频在线观看| 在线免费精品视频| 日本xxx在线播放| 99伊人成综合| 国产在线精品一区| 大黄网站在线观看| 亚洲第一国产精品| 国产亚洲小视频| 国产99精品在线观看| 亚洲精品少妇一区二区| 欧美成年网站| 九九综合九九综合| 国内老熟妇对白hdxxxx| 亚洲激情网站免费观看| 日韩精品xxx| 国内精品久久久久久久影视麻豆 | 国产视频亚洲精品| 国产成人亚洲欧洲在线| 99re8在线精品视频免费播放| 免费av观看网址| 亚洲第一论坛sis| 清纯唯美亚洲综合| 国产一二在线观看| 欧美三级日韩三级| www.99re6| 国产一区二区三区免费在线观看| 女人床在线观看| 99久久人爽人人添人人澡| 国内精品久久久| 久青草国产在线| 欧美天堂一区二区三区| 久久成人小视频| 国产成人日日夜夜| 国产亚洲综合视频| 日韩免费久久| 亚洲综合在线小说| 成人黄色动漫| 在线观看欧美成人| www.亚洲欧美| 黄色成人av网| 久久久久久久久福利| 狠狠久久亚洲欧美| 久久99中文字幕| 红桃视频在线观看一区二区| 成人黄色在线免费| av日韩中文| 一区二区三区视频免费| 99久久精品国产一区色| 午夜影视日本亚洲欧洲精品| 蜜桃传媒一区二区亚洲| 国产精品一二三四区| 亚洲中文字幕无码中文字| 日本不卡免费一区| 成人av播放| 天天综合网站| 久久久久久久久久国产精品| 韩国中文字幕2020精品| 日韩西西人体444www| 一区二区三区在线观看av| 自拍偷拍亚洲综合| 中日韩精品一区二区三区| 国产乱码精品一品二品| 成年人在线看片| 欧美91精品| 日韩精品一区二区三区色偷偷| 57pao国产一区二区| 国产精品v片在线观看不卡| 日本色护士高潮视频在线观看| 亚洲区在线播放| 亚洲精品一区二区三区四区| 欧美日韩综合在线免费观看| 日本最新中文字幕| 亚洲欧美电影一区二区| 美国黄色一级毛片| 国产福利一区在线观看| 欧美三级理论片| 午夜在线一区| av在线免费观看国产| 三上亚洲一区二区| 美女主播视频一区| aaa国产精品视频| 91精品国产综合久久久久久蜜臀| 在线高清av| 久久久久久国产免费| 国产在线观看av| 中文字幕在线日韩| 国产乱理伦片a级在线观看| 亚洲精品动漫久久久久| 亚洲精品国产手机| 欧美一区在线视频| 一级成人免费视频| 欧美日韩中文字幕精品| 亚洲精品久久久久久久蜜桃| 精品久久久一区| 国产一级做a爰片在线看免费| 自拍偷拍欧美精品| 91精品一区二区三区蜜桃| 中文字幕欧美激情一区| 午夜理伦三级做爰电影| 99久久99久久免费精品蜜臀| 日本一区二区免费视频| 成人一区二区三区视频| 涩视频在线观看| 福利电影一区二区| 成人区人妻精品一区二| 国产91高潮流白浆在线麻豆| 色偷偷中文字幕| 国产综合色产在线精品| 99九九99九九九99九他书对| 久久黄色级2电影| 日本xxxx黄色| 美女视频黄 久久| 日韩中文字幕a| 蜜臀av国产精品久久久久 | 黄色污污视频在线观看| 欧美激情视频给我| 变态调教一区二区三区| 91成人在线播放| 欧美aaa视频| 国产精品影院在线观看| 国产精品美女午夜爽爽| 国产日韩一区在线| 国产亚洲亚洲国产一二区| 91在线观看网站| 成人性生交大片免费看中文视频| 国产伦视频一区二区三区| 亚洲午夜久久| 先锋影音网一区| 亚洲成av人电影| 国产乱子伦精品无码专区| 一本色道久久精品| 已婚少妇美妙人妻系列| 久久国产精品无码网站| 久草福利在线观看| eeuss影院一区二区三区| 一本加勒比北条麻妃| 国产精品丝袜一区| 精品一区在线观看视频| 天天操天天色综合| 伊人网站在线观看| 日韩美一区二区三区| av女名字大全列表| 色伦专区97中文字幕| 国精一区二区三区| 国产精品a久久久久久| 成人在线视频www| 黑人巨大精品欧美一区二区小视频| 三级小说欧洲区亚洲区| 亚洲午夜精品一区二区三区| 国产精品观看| 一级黄色香蕉视频| 国产成+人+日韩+欧美+亚洲| 丰满少妇一区二区| 亚洲黄一区二区三区| 天堂а√在线中文在线新版| 这里只有精品99re| 亚洲av成人精品日韩在线播放| 少妇激情综合网| 美女精品导航| 国产日韩中文字幕| www国产精品| 亚洲精品一区二区三区四区五区 | 青青青在线视频播放| 裸体在线国模精品偷拍| 中文字幕乱视频| 国产精品欧美一区二区三区| 午夜影院在线看| 欧美男女性生活在线直播观看| 日韩中文字幕综合| 欧美成人剧情片在线观看| 超级碰碰久久| 成人av播放| 911精品美国片911久久久| 女人扒开屁股爽桶30分钟| 国产999精品久久久久久绿帽| 国产18无套直看片| 色偷偷88欧美精品久久久| 亚洲精品一区二区三区区别| yw.139尤物在线精品视频| 中文字幕这里只有精品| 国产精品国色综合久久| 久久久久亚洲| www.涩涩涩| 久久久综合精品| 日韩精品视频播放| 欧美mv日韩mv国产网站app| 欧美18一19xxx性| 51午夜精品视频| 国产精品2023| 成人av在线播放观看| 韩国三级电影一区二区| 日本综合在线观看| 日本韩国一区二区三区| 欧美一区二区少妇| 2020国产精品视频| 美女av一区| 日韩欧美精品免费| 岛国精品一区二区| 久久网一区二区| 日韩免费观看高清完整版| 午夜小视频在线观看| 亚洲专区国产精品| 午夜日韩在线| 亚洲成人激情小说| 一区二区三区精品久久久| 国产成人av免费看| 欧美精品18videos性欧| 一区二区三区在线免费看| 国产 欧美 日韩 一区| 国产成人av影院| 久久精品视频8| 精品国产一区二区三区av性色 | 欧美二区在线播放| 午夜电影一区| 免费网站在线观看视频| 国产超碰在线一区| 日韩特黄一级片| 日韩成人在线电影网| 亚洲美女久久精品| 日韩精品久久久毛片一区二区| 日本成人在线不卡视频| 天堂资源在线视频| 69av一区二区三区| 狂野欧美性猛交xxxxx视频| 国产一区二区不卡视频| 亚洲欧美清纯在线制服| 久久久久久国产免费a片| 欧美日韩国产综合久久| 中中文字幕av在线| 极品校花啪啪激情久久| 久久久亚洲一区| 成人18视频免费69| 日韩欧美一二三四区| 高潮在线视频| 日韩精品一区二区三区四区五区| 久久国产三级精品| 久久久久久久久久99| 国产视频在线一区二区| 国产激情欧美| 欧美人与动牲交xxxxbbbb| 97se亚洲国产综合自在线观| 日批视频免费观看| 美日韩丰满少妇在线观看| 欧美三级午夜理伦三级在线观看| 五月婷婷丁香综合网| 亚洲资源在线观看| jizz视频在线观看|