日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c++ websocket客户端_websocket使用

發布時間:2025/3/11 c/c++ 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++ websocket客户端_websocket使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
websocket使用

一、介紹

????在項目開發過程中,很多時候,我們不可避免的需要實現的一個功能:??

服務端實時發送信息給客戶端。比如實時公告、實時訂單通知、實時報警推送等等,登錄后的客戶端需要知道與它相關的實時信息,以便進行下一步處理。

????從事服務端開發的特別是C/C++開發的技術人員都知道,客戶端可以通過套接口與服務端保持套接口長連接。這樣就服務端就可以實時給客戶端推送信息了,但是這是針對TCP的長連接,如果是針對HTTP協議(在TCP層之上的實現了超文本協議的短鏈接--一般情況下短鏈接),實現服務端與客戶端通知一般有一下兩種方式:

1、HTTP輪詢

一般情況下,http是短鏈接,也就是請求響應式的,每一次請求都對應一次回復,回復完成后連接斷開,這樣做的好處就是不需要保持與服務端的長連接,因為HTTP協議底層還是TCP協議,服務端根據機器性能都有一個最大的套接口連接數限制。以windows為例子,如windows下TCP連接數受多個參數影響:

  • 最大tcp連接數

[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters]
TcpNumConnections = 0x00fffffe (Default = 16,777,214)

以上注冊表信息配置單機的最大允許的TCP連接數,默認為 16M。這個數值看似很大,這個并不是限制最大連接數的唯一條件,還有其他條件會限制到TCP 連接的最大連接數。

  • 最大動態端口數
    TCP客戶端和服務器連接時,客戶端必須分配一個動態端口,默認情況下這個動態端口的分配范圍為 1024-5000 ,也就是說默認情況下,客戶端最多可以同時發起3977個Socket連接。我們可以修改如下注冊表來調整這個動態端口的范圍.

[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters]
MaxUserPort = 5000 (Default = 5000, Max = 65534)

最大調整值65535,也就是最大能有6w多tcp連接

  • 最大TCB數量
    系統為每個TCP連接分配一個TCP控制塊(TCP control block or TCB),這個控制塊用于緩存TCP連接的一些參數,每個TCB需要分配 0.5 KB的pagepool 和 0.5KB 的Non-pagepool,也就說,每個TCP連接會占用 1KB 的系統內存。換句話說TCP的連接數也受到系統的內存的限制。系統的最大TCB數量由如下注冊表設置決定:

[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters]
MaxFreeTcbs = 2000 (Default = RAM dependent, but usual Pro = 1000, Srv=2000)

非Server版本,MaxFreeTcbs 的默認值為1000(64M 以上物理內存),Server 版本,這個的默認值為 2000。也就是說,默認情況下,Server版本最多同時可以建立并保持2000個TCP連接

  • 最大TCB Hash table數量
    TCB是通過Hash table來管理的,下面注冊表設置決定了這個Hash table的大小

HKEY_LOCAL_MACHINE \System \CurrentControlSet \services \Tcpip \Parameters]
MaxHashTableSize = 512 (Default = 512, Range = 64-65536)

指明分配pagepool內存的數量,也就是說,如果MaxFreeTcbs = 1000, 則pagepool的內存數量為500KB那么 MaxHashTableSize應大于500才行。這個數量越大,則Hash table的冗余度就越高,每次分配和查找TCP.這里 MaxHashTableSize被配置為比MaxFreeTcbs大4倍,這樣可以大大增加TCP建立的速度。

????知道了底層TCP限制之后,我們可以知道實際上長連接在普通的windows機器上最多大概是1000路左右,也就并發是1000個http長連接。如果將長連接改為http短鏈接,http請求完成后立即釋放,那么服務端的并發就會大大增加,如果請求速度不太耗時,服務端的并發量有可能達到1w或者更大!!!c
????使用HTTP輪詢,就是使用HTTP短鏈接模式,定期與服務端進行通信主動獲取服務端信息的方式實現服務端“推送”信息至客戶端,它有如下特點:

  • 避免與服務端的長連接,減低服務端壓力,提升服務端的并發訪問能力

  • 客戶端主動與服務端通信,需要定期與服務端進行輪詢查詢獲取信息,但對客戶端而言存在延遲,延遲時間最大為輪詢時間。

  • 服務端需要做額外的工作包保存一些實時數據,等待客戶端拉取。

2、websocket

??? http長輪詢因為存在信息延遲的問題,有時候,我們需要實時收到服務端推送的信息就無法避免使用websocket了。在前面我已經說到,websocket實際上也是http升級upgrade之后的tcp長連接,長連接的數量限制經過調整后最大能有(65525-1024)= 64501個長連接(在內存、句柄數等不設限情況下)。但實際測試,可能服務端的websocket連接數可能維持的2w左右(經過實際測試),如果改為云主機,連接數可能達到6w左右。如果需要更多了連接,我們可以考慮集群的方式,如n臺高性能機器能支持最大n*6w的websocket連接!!它有如下優點:

  • WebSocket一次握手就可以使客戶端和服務端建立長連接,并進行雙向數據傳輸

  • 服務端可主動向客戶端發送信息,實時性很高

  • 與HTTP協議比起來,WebSocket協議每次數據傳輸的頭信息都較小,節約帶寬

針對瀏覽器本身,連接后臺最大的websocket數量也是有限制的,以下是我搜索到的各個瀏覽器支持的最大websocket連接數:

IE 6個
chrome 256個
Firefox 200個
safari 1273個(MAC版本)

超過各個瀏覽器最大數,后臺就收不到請求。

二、 websocket實現

說明了原理之后,接下來就是如何實現websocket,這里我提供了幾種實現方式

1、J2EE7自帶的原始實現

服務端實現
WebSocket是JavaEE7新支持的,Javax.websocket.server包含注解、類、接口用于創建和配置服務端點;Javax.websocket包則包含服務端點和客戶斷電公用的注解、類、接口、異常,創建一個注解式的端點,將自己的寫的類以及類中的一些方法用前面提到的包中的注解裝飾,這里我提供了一個基本的websocket實現接口,提供了連接、關閉、接收消息、發送消息接口:

package com.easystudy.websocket;

import java.io.IOException;
import javax.websocket.Session;
import lombok.extern.slf4j.Slf4j;

/**
* @歡迎加入群聊,一起分享,一起合作,一起進步
* QQ交流群:961179337
* 微信賬號:lixiang6153
* 微信公眾號:IT技術快餐
* 電子郵箱:lixx2048@163.com
*/
@Slf4j
public abstract class BaseWS {
/**
* 終端初次連接
* @param userId userId
* @param session session
* @throws IOException IOException
*/
abstract void onOpen(Session session, Long userId) throws IOException;

/**
* 終端斷開連接
*/
abstract void onClose();

/**
* 終端傳遞參數
* @param session session
* @param message message
*/
abstract void onMessage(String message, Session session);

/**
* 報錯
* @param session session
* @param error error
*/
abstract void onError(Session session, Throwable error);

/**
* 向終端發送
* @param message message
* @throws IOException IOException
*/
abstract void sendMessage(String message) throws IOException;

void heartBeat(Long user, String signal, Session session) {
if ("ping".equalsIgnoreCase(signal)) {
try {
log.info("heart beat=====> {},user:{}, sessionId:{}", signal, user, session.getId());
session.getBasicRemote().sendText("pong");
log.info("heart beat<====> {},user:{}, sessionId:{}", "pong", user, session.getId());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

websocket端點實現:

package com.easystudy.websocket;

import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import org.springframework.stereotype.Component;

/**
* @ServerEndpoint 該注解可以將類定義成一個WebSocket服務器端,
* @OnOpen 表示有瀏覽器鏈接過來的時候被調用
* @OnClose 表示瀏覽器發出關閉請求的時候被調用
* @OnMessage 表示瀏覽器發消息的時候被調用
* @OnError 表示報錯了
* @歡迎加入群聊,一起分享,一起合作,一起進步
* QQ交流群:961179337
* 微信賬號:lixiang6153
* 微信公眾號:IT技術快餐
* 電子郵箱:lixx2048@163.com
*/
@Component
@ServerEndpoint("/ws/msg/{userid}")
public class MessageEndPoint extends BaseWS {
// concurrent包下線程安全的Set
private static final CopyOnWriteArraySet SESSIONS = new CopyOnWriteArraySet<>();
private Session session;
@Override
@OnOpen
public void onOpen(Session session, @PathParam("userid") Long userid) {
this.session = session;
SESSIONS.add(this);
System.out.println(String.format(userid + "成功建立連接~ 當前總連接數為:%s", SESSIONS.size()));
System.out.println(this);
}
@Override
@OnClose
public void onClose() {
SESSIONS.remove(this);
System.out.println(String.format("成功關閉連接~ 當前總連接數為:%s", SESSIONS.size()));
}
@Override
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("收到客戶端【" +session.getId()+ "】消息:" + message);
}
@Override
@OnError
public void onError(Session session, Throwable error) {
System.out.println("發生錯誤");
error.printStackTrace();
}
/**
* 指定發消息
* @param message
*/
public void sendMessage(String message) {
try {
this.session.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 群發消息: 靜態方法
* @param message
*/
public static void fanoutMessage(String message) {
SESSIONS.forEach(ws -> ws.sendMessage(message));
}
}

我們監聽的端點是

/ws/msg/{userid}

端點攜帶了一個參數userid,表示長連接的用戶id,我們在對應的方法實現中通過注解引用對應參數即可。

我們使用J2EE7標準注解,必須注入相應的ServerEndpointExporter類:

@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}

最后,我們提供一個controller用于測試服務端往發送客戶端信息:

package com.easystudy.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.easystudy.websocket.MessageEndPoint;

@RestController
@RequestMapping("/response")
public class TestController {

@GetMapping("/send")
public String reponseMsgToClient(@RequestParam(name="content", required = true)String content){
System.out.println("發送消息:[" + content + "]給客戶端!");

MessageEndPoint.fanoutMessage(content);

return "消息【" +content+ "】發送成功!";
}
}

客戶端實現
在實現websocket服務端之后,我們就需要實現websocket客戶端,連接到服務器,接收服務端消息,實現代碼如下所示:





websocket測試





WebSocket Demo





服務器回復內容:

發送



啟動瀏覽器,打開控制臺,可以看到連接到服務器字樣,輸入內容,點擊發送,服務端后臺打印接收到客戶端信息并廣播到客戶端,客戶端控制臺也打印了相同字樣。

2、springboot實現

除了J2EE原始實現之外,使用springboot之后,功能就更強大了,它提供了一個核心的配置類WebSocketConfigurer用于注冊各種websocket端點、攔截器、處理器信息。如下我們通過繼承WebSocketConfigurer配置對應端點、處理器和攔截器:

package com.easystudy.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

import com.easystudy.websocket.MsgWebSocketHandler;
import com.easystudy.websocket.MsgWebSocketInterceptor;

@Configuration
@EnableWebSocket
public class WebsocketConfig implements WebSocketConfigurer {

@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
// 設置端點連接路徑和處理器
registry.addHandler(new MsgWebSocketHandler(), "/ws/msg/{userid}")
.setAllowedOrigins("*")
// 設置攔截器
.addInterceptors(new MsgWebSocketInterceptor());
}

}

我們配置了自己的處理器處理對應端點、配置了攔截器進行信息攔截。

我這里的攔截器主要攔截請求參數,限定請求參數必須攜帶用戶名作為連接的唯一標識:

package com.easystudy.websocket;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

/**
* 自定義攔截器攔截WebSocket請求
* @author Administrator
* QQ交流群:961179337
* 微信賬號:lixiang6153
* 微信公眾號:IT技術快餐
* 電子郵箱:lixx2048@163.com
*/
public class MsgWebSocketInterceptor implements HandshakeInterceptor{

/**
* 前置攔截一般用來注冊用戶信息,綁定 WebSocketSession
*/
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Map attributes) throws Exception {
System.out.println("前置攔截~~");
if (!(request instanceof ServletServerHttpRequest))
return true;
// 獲取用戶名信息
HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();
String path = servletRequest.getServletPath();
System.out.println("path:" + path);
String userName = servletRequest.getParameter("userName");
//String userName = (String) servletRequest.getSession().getAttribute("userName");
if (null == userName) {
userName = "lixx";
}
// 保存屬性到session屬性信息中
attributes.put("userName", userName);
return true;
}
/**
* 后置攔截器
*/
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
System.out.println("后置攔截~~");
}
}

攔截器獲取到對應屬性之后存入到session的會話屬性之中,連接之后可以通過session獲取會話屬性。

處理器實現:

package com.easystudy.websocket;

import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;

import org.springframework.web.socket.*;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
* QQ交流群:961179337
* 微信賬號:lixiang6153
* 微信公眾號:IT技術快餐
* 電子郵箱:lixx2048@163.com
*/
public class MsgWebSocketHandler implements WebSocketHandler{
private static final Map SESSIONS = new ConcurrentHashMap<>();
/**
* 建立新的 socket 連接后回調的方法
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
String userName = session.getAttributes().get("userName").toString();
SESSIONS.put(userName, session);
System.out.println(String.format("成功建立連接~ userName: %s", userName));
}
/**
* 連接關閉時,回調的方法
*/
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
System.out.println("連接已關閉,status:" + closeStatus);
}
/**
* 接收客戶端發送的 Socket
*/
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage> message) throws Exception {
String msg = message.getPayload().toString();
System.out.println("接收到消息:" + msg);
}
/**
* 連接出錯時,回調的方法
*/
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
System.out.println("連接出錯");
if (session.isOpen()) {
session.close();
}
}
/**
* 這個是 WebSocketHandler是否處理部分消息,返回 false就完事了
*/
@Override
public boolean supportsPartialMessages() {
return false;
}
/**
* 指定發消息
* @param userName
* @param message
*/
public static void sendMessage(String userName, String message) {
WebSocketSession webSocketSession = SESSIONS.get(userName);
if (webSocketSession == null || !webSocketSession.isOpen())
return;
try {
webSocketSession.sendMessage(new TextMessage(message));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 群發消息
* @param message
*/
public static void fanoutMessage(String message) {
SESSIONS.keySet().forEach(us -> sendMessage(us, message));
}
}

在建立連接之后,我們通過:session.getAttributes().get("userName").toString();獲取到連接時候提供的用戶參數,用于后續指定用戶P2P發送信息。

客戶端實現代碼如下:





測試





WebSocket Demo





服務器回復內容:

發送



最后測試發送信息如下:

3、socketJS實現

一些瀏覽器中缺少對WebSocket的支持,因此,回退選項是必要的,而Spring框架提供了基于SockJS協議的透明的回退選項。SockJS的一大好處在于提供了瀏覽器兼容性。優先使用原生WebSocket,如果在不支持websocket的瀏覽器中,會自動降為輪詢的方式。

SockJS是一個瀏覽器JavaScript庫,它提供了一個類似于網絡的對象。SockJS提供了一個連貫的、跨瀏覽器的Javascript API,它在瀏覽器和web服務器之間創建了一個低延遲、全雙工、跨域通信通道。除此之外,spring也對socketJS提供了支持。此處實現與springboot實現相似,這里不具體介紹,只給出對應代碼,實現如下(后續提供的代碼是實際項目上的代碼,請各位保持修改個更新,謝謝!!!)。

端點、攔截器、通道等配置如下

package com.donwait.websocket;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.ChannelRegistration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration;

/**
* 同 HTTP 在 TCP 套接字上添加 請求-響應 模型層一樣,STOMP 在 WebSocket 之上提供了一個基于 幀的線路格式層,用來定義消息語義;
* (STOMP在 WebSocket 之上提供了一個基于 幀的線路格式層,用來定義消息語義)
* STOMP 幀:該幀由命令,一個或多個 頭信息 以及 負載所組成。如下就是發送 數據的一個 STOMP幀:
* SEND
* destination:/app/marco
* content-length:20
*
* {\"message\":\"Marco!\"}
*
* 分析:
* A1)SEND:STOMP命令,表明會發送一些內容;
* A2)destination:頭信息,用來表示消息發送到哪里;
* A3)content-length:頭信息,用來表示 負載內容的 大小;
* A4)空行:
* A5)幀內容(負載)內容:
*/
@Configuration
@EnableWebSocketMessageBroker // 能夠在 WebSocket 上啟用 STOMP
public class WebSocketAutoConfig implements WebSocketMessageBrokerConfigurer {
/*
* 將 "/dys" 路徑 注冊為 STOMP 端點,即客戶端在訂閱或發布消息 到目的地址前,要連接該端點,
* 就是說用戶發送請求 url='/項目名/dys'與 STOMP server進行連接,之后再轉發到訂閱url
* 端點的作用:客戶端在訂閱或發布消息 到目的地址前,要連接該端點
* 備注:client連接地址和發送地址是不同的,以本例為例,前者是/項目名/dys, 后者是/項目名/app/XX,先連接后發送
*/
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
// 在網頁上我們就可以通過這個鏈接 /demon/websocket ==來和服務器的WebSocket連接
// 連接:new SockJS("http://127.0.0.1:7019/websocket/dys");
registry.addEndpoint("/dys") // 開啟 /dys端點
.setAllowedOrigins("*") // 允許跨域訪問
.setHandshakeHandler(new HandshakeHandler()) // 握手處理器
.addInterceptors(new HandshakeInterceptor()) // 握手攔截器
.withSockJS(); // 允許使用socketJs方式訪問
}
/*
* 消息傳輸參數配置
*/
@Override
public void configureWebSocketTransport(WebSocketTransportRegistration registry) {
registry.setMessageSizeLimit(8192) // 設置消息字節數大小
.setSendBufferSizeLimit(8192) // 設置消息緩存大小
.setSendTimeLimit(10000); // 設置消息發送時間限制毫秒
}
/*
* 輸入通道參數設置
*/
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.taskExecutor().corePoolSize(8) // 設置消息輸入通道的線程池線程數
.maxPoolSize(16) // 最大線程數
.keepAliveSeconds(60); // 線程活動時間
registration.interceptors(createUserInterceptor()); // 注入用戶入站通道攔截器
}
/*
* 輸出通道參數設置
*/
@Override
public void configureClientOutboundChannel(ChannelRegistration registration) {
registration.taskExecutor().corePoolSize(8)
.maxPoolSize(16);
}
/*
* 配置broker:
* 配置了一個 簡單的消息代理。如果不重載,默認case下,會自動配置一個簡單的內存消息代理,
* 用來處理 "/topic"為前綴的消息。但經過重載后,消息代理將會處理前綴為 "/topic" and "/queue"消息
* 分析:
* (1)應用程序的目的地 以 "/app" 為前綴,而代理的目的地以 "/topic" 和 "/queue" 作為前綴
* (2)以應用程序為目的地的消息將會直接路由到 帶有 @MessageMapping注解的控制器方法中
* (3)而發送到代理上的消息,包括 @MessageMapping注解方法的返回值所形成的消息,將會路由到代理上,并最終發送到訂閱這些目的地客戶端
*/
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
// 代理的目的地址為topic或queque(代理目的地以 /topic為前綴)
// 廣播消息訂閱:stompClient.subscribe('/topic/alarm', function (response)
registry.enableSimpleBroker("/topic", "/queue");
// 全局使用的消息前綴(客戶端訂閱路徑上會體現出來):應用程序前綴:js.url = "/demon/app/hello" -> @MessageMapping("/hello") 注釋的方法.
// 客戶端發送端點前綴:stompClient.send("/app/hello", {}, JSON.stringify({ 'name': name }));
registry.setApplicationDestinationPrefixes("/app");
// 點對點使用的訂閱前綴(客戶端訂閱路徑上會體現出來),不設置的話,默認也是/user/
// registry.setUserDestinationPrefix("/user/");
/*
// 啟用了STOMP代理中繼功能,并將其代理目的地前綴設置為 /topic and /queue,并將所有目的地前綴為 "/topic" or "/queue"的消息都會發送到STOMP代理中[真正消息代理activeMQ或RabbitMQ]
registry.enableStompBrokerRelay("/topic", "/queue") // 設置可以訂閱的地址,也就是服務器可以發送的地址
.setRelayHost("192.168.12.18")
.setRelayPort(5672)
.setClientLogin("admin")
.setClientPasscode("admin")
.setSystemHeartbeatReceiveInterval(2000) // 設置心跳信息接收時間間隔
.setSystemHeartbeatSendInterval(2000); // 設置心跳信息發送時間間隔
// 應用程序前綴:js.url = "/demon/app/hello" -> @MessageMapping("/hello") 注釋的方法.
registry.setApplicationDestinationPrefixes("/app");
*/
}
/**
*
* @Title: createUserInterceptor
* @Description: 將客戶端渠道攔截器加入spring ioc容器
* @return
*/
@Bean
public UserInterceptor createUserInterceptor() {
return new UserInterceptor();
}
}

握手攔截器配置:

package com.donwait.websocket;

import java.util.Map;

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {

@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,Map attributes) throws Exception {
log.info("============握手前===========");
/*
// 解決The extension [x-webkit-deflate-frame] is not supported問題
if(request.getHeaders().containsKey("Sec-WebSocket-Extensions")) {
request.getHeaders().set("Sec-WebSocket-Extensions", "permessage-deflate");
}
// 檢查session的值是否存在
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
HttpSession session = servletRequest.getServletRequest().getSession(false);
String accountId = (String) session.getAttribute(Constants.SKEY_ACCOUNT_ID);
//把session和accountId存放起來
attributes.put(Constants.SESSIONID, session.getId());
attributes.put(Constants.SKEY_ACCOUNT_ID, accountId);
}
*/
return super.beforeHandshake(request, response, wsHandler, attributes);
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,Exception ex) {
log.info("============握手后===========");
super.afterHandshake(request, response, wsHandler, ex);
}
}

用戶攔截器配置:

package com.donwait.websocket;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.stomp.StompCommand;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.messaging.support.ChannelInterceptorAdapter;
import org.springframework.messaging.support.MessageHeaderAccessor;

import com.donwait.amqp.RabbitMQ;
import com.donwait.model.RtmpInviteInfo;
import com.donwait.model.User;
import com.donwait.protobuf.RTMP_INVITE_PARAM;
import com.donwait.redis.RtmpInviteService;

/**
* @ClassName: UserInterceptor
* @Description: 客戶端渠道攔截適配器
*/
@SuppressWarnings("deprecation")
public class UserInterceptor extends ChannelInterceptorAdapter {
@Autowired
private RtmpInviteService redisRtmpInviteService;
@Autowired
private RabbitMQ rabbitMQ;
//@Autowired
//private UserCacheService userCacheService;

/**
* 獲取包含在stomp中的用戶信息
*/
@SuppressWarnings("rawtypes")
@Override
public Message> preSend(Message> message, MessageChannel channel) {
StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
if (StompCommand.CONNECT.equals(accessor.getCommand())) {
Object raw = message.getHeaders().get(SimpMessageHeaderAccessor.NATIVE_HEADERS);
if (raw instanceof Map) {
Object name = ((Map) raw).get("name");
if (name instanceof LinkedList) {
// 設置當前訪問器的認證用戶
accessor.setUser(new User(((LinkedList) name).get(0).toString()));
}
}
}
return message;
}

@Override
public void postSend(Message> message, MessageChannel channel, boolean sent) {
StompHeaderAccessor sha = StompHeaderAccessor.wrap(message);
// ignore non-STOMP messages like heartbeat messages
if(sha.getCommand() == null) {
return;
}

//這里的sessionId和accountId對應HttpSessionIdHandshakeInterceptor攔截器的存放key
//String sessionId = sha.getSessionAttributes().get(Constants.SESSIONID).toString();
//String accountId = sha.getSessionAttributes().get(Constants.SKEY_ACCOUNT_ID).toString();
//判斷客戶端的連接狀態
switch(sha.getCommand()) {
case CONNECT:
connect(sha);
break;
case CONNECTED:
break;
case DISCONNECT:
disconnect(sha);
break;
default:
break;
}
}

// 連接成功
private void connect(StompHeaderAccessor sha){
System.out.println(" STOMP 連接成功:" + sha.getUser().getName());
}

// 斷開連接
private void disconnect(StompHeaderAccessor sha){
System.out.println(" STOMP 連接斷開" + sha.getUser().getName());

// 移除用戶信息
//userCacheService.delete(sha.getUser().getName());

String strKey = String.format("rtmp_invite_info::%s_*", sha.getUser().getName());
List invite_list = redisRtmpInviteService.findByKeyEx(strKey);
if (invite_list != null) {
for(RtmpInviteInfo rtmpInviteInfo : invite_list){
// 通知接入服務器
RTMP_INVITE_PARAM.Builder builder = RTMP_INVITE_PARAM.newBuilder();
builder.setRtmpIP(rtmpInviteInfo.getRtmpIp());
builder.setRtmpPort(rtmpInviteInfo.getRtmpPort());
builder.setDevID(rtmpInviteInfo.getDevId());
builder.setProtocolType(rtmpInviteInfo.getProtoType());
builder.setStreamType(rtmpInviteInfo.getStreamType());
rabbitMQ.send(rtmpInviteInfo.getExchangeName(), rtmpInviteInfo.getRouteKey(), builder.build().toByteArray());
strKey = String.format("%s::%s_%s_%d_%d_%d", rtmpInviteInfo.getCacheName(), sha.getUser().getName(), rtmpInviteInfo.getDevId(), rtmpInviteInfo.getChannelNum().longValue(), rtmpInviteInfo.getProtoType().longValue(), rtmpInviteInfo.getStreamType().longValue());
redisRtmpInviteService.deleteByKey(strKey);
}
}
}
}

處理器代碼:

package com.donwait.websocket;

import org.springframework.web.socket.server.support.DefaultHandshakeHandler;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class HandshakeHandler extends DefaultHandshakeHandler{

public HandshakeHandler(){
log.debug("new HandshakeHandler");
}
}

配置完成之后,需要封裝一個消息服務實現點對點和廣播形式發送:

package com.donwait.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.messaging.simp.user.SimpUser;
import org.springframework.messaging.simp.user.SimpUserRegistry;
import org.springframework.stereotype.Service;

/**
* websocket廣播推送服務
* @author Administrator
*
*/
@Service
public class MessageService {
@Autowired
SimpMessageSendingOperations sendOperation; // 消息發送模板
@Autowired
private SimpUserRegistry userRegistry; // 用戶列表【連接的客戶端信息】

/**
* 廣播形式發送報警信息
* @param
*/
public void broadcast(String destination,String message) {
sendOperation.convertAndSend(destination, message);
System.out.println("路由:"+ destination + " 推送消息:" + message);
}

/**
* 單獨發送信息給某用戶
* 客戶端發起連接時候必須攜帶用戶名參數
* stompClient.connect(
* {
* name: 'lixx' // 攜帶客戶端信息
* }
* @param
*/
public void send(String destination,String username, String message) {
for (SimpUser user : userRegistry.getUsers()) {
if (user.getName().equals(username)){
sendOperation.convertAndSendToUser(username, destination, message);
System.out.println("路由:"+ destination + " 推送消息:" + message);
break;
}
}
}
}

最后,送上測試的html客戶端頁面:




stomp



Welcome

發送消息
訂閱用戶消息/user/queue/message
訂閱報警消息/topic/alarm







至此,websocket的具體介紹與實例都已送上,如果需要源碼或者技術交流或者合作請聯系一下方式

源碼獲取、合作、技術交流請獲取如下聯系方式:

QQ交流群:961179337

微信賬號:lixiang6153
公眾號:IT技術快餐
電子郵箱:lixx2048@163.com

總結

以上是生活随笔為你收集整理的c++ websocket客户端_websocket使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

最新日韩中文字幕 | av中文资源在线 | 久二影院 | 日韩av综合网站 | 亚洲精品国偷拍自产在线观看蜜桃 | 亚洲欧美日韩一二三区 | 六月丁香激情网 | 在线视频日韩精品 | 国产精品乱码一区二区视频 | 亚洲欧美偷拍另类 | 黄色毛片大全 | 久久久久国产成人精品亚洲午夜 | 天天玩天天操天天射 | 97香蕉超级碰碰久久免费软件 | 日韩精品高清视频 | 午夜精品福利一区二区 | 精品嫩模福利一区二区蜜臀 | 月丁香婷婷 | 国产特级毛片aaaaaa | 国产美腿白丝袜足在线av | 天天操偷偷干 | 在线亚洲日本 | 五月天婷婷视频 | 91麻豆免费版 | 狠狠干婷婷色 | 午夜久久久精品 | 久久久久久黄色 | 国产日韩av在线 | 久久久久久久久爱 | 国产在线黄色 | 九七视频在线 | 国产亚洲情侣一区二区无 | 久久久久久久久久久久久久电影 | 2021久久 | 免费污片 | 国产精品乱码久久久久久1区2区 | 久久夜色电影 | 日韩激情第一页 | 亚洲精品一区二区三区在线观看 | 麻花传媒mv免费观看 | 国产精品尤物视频 | 特级毛片爽www免费版 | 亚洲乱码精品久久久久 | 精品播放 | 亚洲精品永久免费视频 | 日韩簧片在线观看 | 亚洲成人欧美 | 欧美污网站 | 久久成人亚洲欧美电影 | 九九在线视频免费观看 | 97电影网手机版 | 色www.| 久香蕉 | 中文字幕日韩无 | 欧美激情综合五月色丁香 | 极品嫩模被强到高潮呻吟91 | 久久久久久久久久久久久久av | 国产91在线 | 美洲 | 深爱激情五月综合 | 日韩久久网站 | 亚洲精品中文在线观看 | 亚洲91网站 | 人人涩| 丁香网五月天 | 色综合天天做天天爱 | 亚洲欧美经典 | 亚欧日韩成人h片 | 亚洲国产精品久久久久 | 亚洲精品一区中文字幕乱码 | 国产精品久久久久影视 | 国产一区二区三区视频在线 | 亚洲精品在线看 | 97国产情侣爱久久免费观看 | av再线观看 | 91最新在线观看 | 免费精品在线观看 | 久久久久久久久久伊人 | 成人手机在线视频 | 国产成人精品久久久久蜜臀 | 成人国产一区 | 中文字幕在线看视频国产中文版 | 日日精品 | 亚洲最大的av网站 | 国产精品久久久久久久久久不蜜月 | 伊人久在线 | 在线日韩精品视频 | 亚洲国产中文字幕 | 亚洲精品国精品久久99热一 | 日韩在线观看视频中文字幕 | 日韩毛片在线免费观看 | 91看片一区二区三区 | 精品国产免费看 | 亚洲区视频在线观看 | 91精品在线观看视频 | 99精品在线免费在线观看 | 亚洲欧洲久久久 | 国产乱对白刺激视频在线观看女王 | 国产日韩视频在线观看 | 国产日本在线播放 | 日韩av电影中文字幕在线观看 | 亚洲视频第一页 | 亚洲精品成人av在线 | 中文字幕欧美激情 | 色视频网址 | 黄www在线观看 | 国产精品亚洲片在线播放 | 在线国产91| 精品日韩中文字幕 | 日韩美在线观看 | 中文字幕精品视频 | 手机看片国产日韩 | 久久亚洲精品电影 | 欧美日韩在线观看一区 | 国产在线精品区 | 欧美另类色图 | 国产精品视频免费看 | 91人人澡人人爽人人精品 | 一区二区不卡 | 天天干视频在线 | 欧美日韩超碰 | 久久综合欧美精品亚洲一区 | 国产又粗又猛又黄又爽的视频 | 四虎在线观看精品视频 | 亚洲色图色 | 欧美日韩性 | 亚洲人成综合 | 国产精品久久久av | 日韩在线播放欧美字幕 | 五月婷丁香 | 人人超碰在线 | 免费日韩一区二区三区 | 国产露脸91国语对白 | 欧美一区二区三区免费看 | 在线观看亚洲电影 | 黄色精品一区二区 | 天天做天天爱天天综合网 | 午夜久久美女 | www.久久色.com | 久久五月婷婷丁香 | 九九涩涩av台湾日本热热 | 久久大视频 | 日韩欧美在线综合网 | 国产精品每日更新 | h动漫中文字幕 | 99综合电影在线视频 | 亚洲精品五月天 | 日韩av一区二区在线影视 | 国产精品久久久久久久久久99 | 成人av电影免费在线观看 | 国产精品久久电影观看 | 国产精品久久久久久超碰 | 国产不卡免费 | 亚洲黄色高清 | 日本久久久久久 | 日韩午夜电影网 | 欧美成人精品欧美一级乱 | 中文字幕在线不卡国产视频 | 狠狠色丁香久久婷婷综 | 91 在线视频播放 | 欧美国产不卡 | 亚洲精品国产第一综合99久久 | 天天爽夜夜爽精品视频婷婷 | 97品白浆高清久久久久久 | 欧美一区二区在线刺激视频 | 国产亚洲精品久久19p | 热久久免费视频 | 成人a免费看 | 视频一区亚洲 | 国产打女人屁股调教97 | 天天干天天操av | 国产午夜精品理论片在线 | 久久伦理视频 | 国内精品久久久久久久久久久久 | 国产又粗又硬又长又爽的视频 | 美女国产网站 | 贫乳av女优大全 | 热久久影视 | 久久在线观看视频 | 九九久久久 | 国产一区成人在线 | 中文字幕精品一区 | 91精品成人 | 欧美巨乳网 | 国产精品 亚洲精品 | 在线免费观看欧美日韩 | 91久久在线观看 | 色综合久久久久久中文网 | 久操视频在线 | 国产精品久久麻豆 | 一区二区三区电影大全 | 午夜av免费在线观看 | 婷婷丁香五 | 伊人资源视频在线 | 国产精品18久久久久久久久久久久 | 亚洲乱码精品久久久久 | 人人射人人澡 | av在线电影免费观看 | 伊人色综合久久天天 | 久久综合电影 | 91综合在线| 欧美 日韩 国产 中文字幕 | 中文久草| 射射射综合网 | 天堂中文在线视频 | 国产美女视频免费观看的网站 | 国产成人三级在线观看 | 精品专区一区二区 | 久久99精品久久久久婷婷 | 激情黄色av | 久操视频在线 | 亚洲日本韩国一区二区 | 国产99久久九九精品 | 天天操,夜夜操 | www亚洲精品 | 精品国产成人 | 伊人婷婷 | 综合中文字幕 | 中文字幕国内精品 | 精品久久亚洲 | 综合色站导航 | 久久99深爱久久99精品 | 国产成人精品综合久久久久99 | 天天干夜夜想 | 国产综合91 | 天天综合网在线观看 | 91亚洲精品久久久蜜桃 | 操夜夜操 | 免费在线观看av网址 | 成人小视频免费在线观看 | 欧美中文字幕第一页 | 丁香五月亚洲综合在线 | 六月丁香在线视频 | 91精品久久久久久综合乱菊 | 国产精品视频在线观看 | 人人干狠狠操 | www.人人草 | 亚洲欧美成人 | 日韩中文字幕视频在线 | 91网免费观看 | 久久99免费视频 | 在线观看av黄色 | 天天操天天射天天操 | 成人黄色资源 | 日韩黄色免费在线观看 | 亚洲国产精品日韩 | 91在线观看视频 | 婷婷成人综合 | 色噜噜狠狠狠狠色综合 | 欧美在线不卡一区 | 免费高清看电视网站 | 激情www | 最新极品jizzhd欧美 | 久操视频在线播放 | 亚洲一级免费电影 | 91大神精品视频 | 中文字幕在线观看免费观看 | www.天天综合 | 成人黄色在线视频 | 在线观看黄网站 | 91九色蝌蚪视频在线 | 久草在线免费新视频 | 国产精品久久久久久久久久 | 91麻豆精品国产91久久久久久 | 久久999久久 | 99精品观看 | 狠狠色狠狠色终合网 | 99电影456麻豆 | 91最新在线 | 久久久免费精品国产一区二区 | 在线视频中文字幕一区 | 97人人超碰在线 | 99精品国产在热久久下载 | 一区二区不卡高清 | 日韩欧美99| 九九久久成人 | 99爱在线 | 久久综合色综合88 | 欧美成人在线免费观看 | 天天综合天天做天天综合 | 国产精品美女久久久久久久久 | 免费久草视频 | 国产精品美女毛片真酒店 | 国产精彩在线视频 | 在线色亚洲 | 国产精品乱码一区二区视频 | zzijzzij亚洲成熟少妇 | 精品在线观看一区二区三区 | 成人免费91| 免费三级黄色 | 一区 二区电影免费在线观看 | 中文字幕亚洲情99在线 | 中文字幕在线观看国产 | 亚洲国产精久久久久久久 | 天天操天天玩 | 九九九九热精品免费视频点播观看 | 在线看日韩av | av在线播放网址 | 亚洲传媒在线 | 国产一二三四在线视频 | 91黄色小网站 | 国产精品尤物 | 国内丰满少妇猛烈精品播 | 国产精品久久久久国产精品日日 | a午夜在线 | 一本色道久久精品 | 国产一区电影在线观看 | 久久综合偷偷噜噜噜色 | 丝袜美腿亚洲 | 999ZYZ玖玖资源站永久 | 婷婷日日 | 91麻豆产精品久久久久久 | 人人干免费 | 国产一区二区在线免费 | 亚洲精品一区二区三区四区高清 | 成年人电影免费在线观看 | 五月天亚洲综合小说网 | 又黄又爽的视频在线观看网站 | av免费黄色 | 最近中文字幕视频网 | 在线精品视频在线观看高清 | 欧美视频日韩视频 | 婷婷深爱网 | 亚洲精品99久久久久久 | 午夜精品视频一区二区三区在线看 | 亚洲综合视频在线 | 91九色蝌蚪视频在线 | 精品v亚洲v欧美v高清v | 狠狠色丁香婷婷综合久小说久 | 久久视频一区二区 | 中文字幕一区二区三区在线观看 | 国产在线高清精品 | 成人免费观看av | 97色在线| 亚洲欧美成aⅴ人在线观看 四虎在线观看 | 色综合久久88色综合天天人守婷 | 日韩综合视频在线观看 | a级国产片| 黄色成人av| 夜夜夜夜操 | 国产伦精品一区二区三区无广告 | 黄色录像av | 日韩一区二区在线免费观看 | 在线观看黄色av | 天天躁天天躁天天躁婷 | 亚洲免费成人av电影 | 超碰成人网 | 欧美视频99 | 中文在线免费视频 | 天天草天天草 | 激情综合网在线观看 | 亚洲精品免费在线观看视频 | 中文字幕在线国产 | 91精品国自产在线偷拍蜜桃 | 久久久久久久久网站 | 99视频在线免费播放 | 天天操综合网站 | 国产69精品久久99的直播节目 | 麻豆国产精品永久免费视频 | 97爱爱爱 | 午夜精品中文字幕 | 97精品国产一二三产区 | 国产精品视频免费看 | 美女免费视频一区 | 久久综合狠狠综合久久狠狠色综合 | 免费日韩 精品中文字幕视频在线 | 久久精品xxx | 久久久精选 | 国产精品久久久一区二区三区网站 | 日韩av高潮 | 成人蜜桃视频 | 国产一二区视频 | 国产亚洲精品久久久久动 | 国产精品日韩欧美一区二区 | 最近日本韩国中文字幕 | 久久久久久精 | 国产黄色理论片 | 91高清免费在线观看 | 91精品资源 | 91精品国产麻豆 | 99久久超碰中文字幕伊人 | 97狠狠操 | 久久久精品综合 | 91色网址 | 天天插天天狠 | 亚洲 中文字幕av | 日本韩国精品在线 | 成人资源在线观看 | 久久久久久久久久久黄色 | 亚洲激情一区二区三区 | 色国产视频 | 人人超在线公开视频 | 日韩精品一区二区三区不卡 | av免费黄色| 日精品在线观看 | 尤物九九久久国产精品的分类 | 91av视频| 天天色天天搞 | av黄色免费看 | 日韩中文字幕免费在线观看 | 免费a级观看 | 日韩欧美视频免费看 | 久青草视频 | 四虎在线免费观看 | 中文字幕日韩av | 日韩免费久久 | 有码中文字幕 | 免费h在线观看 | 婷婷色亚洲 | 91在线看黄 | 狠狠躁夜夜躁人人爽视频 | 丁香五月亚洲综合在线 | 国产精品v欧美精品v日韩 | www.国产精品 | 国产成人精品女人久久久 | 久热精品国产 | 五月婷婷六月综合 | 九九热免费在线视频 | 免费在线激情电影 | 国产成人l区 | 免费在线观看av网站 | 99久久久成人国产精品 | 永久免费看av | 亚洲经典精品 | 国产精品视频永久免费播放 | 日韩高清免费观看 | 国产精品国产三级国产aⅴ入口 | 日韩a在线看 | 精品影院| 日韩精选在线 | 99视频这里有精品 | 最新av在线网站 | 免费毛片一区二区三区久久久 | 97在线影视 | 黄色片视频免费 | 天天爽天天摸 | 天堂在线视频中文网 | 国产夫妻性生活自拍 | 久草网站在线观看 | 国产亚洲在线 | 午夜精品一区二区三区可下载 | 麻豆 91 在线| 亚洲精品欧美视频 | 四虎4hu永久免费 | 国产视频二区三区 | 亚洲三级视频 | 91视频91自拍| 99国产精品视频免费观看一公开 | 麻豆精品在线视频 | 在线成人免费 | 久久精品影视 | 国产日韩精品一区二区在线观看播放 | 亚洲国产wwwccc36天堂 | 天天在线免费视频 | 亚洲欧洲日韩 | 日韩资源在线 | av在线一级| 免费看的黄色片 | 69av在线播放 | 亚洲精品久久久久58 | 免费观看的黄色片 | 青青久草在线视频 | 欧美综合在线观看 | 精品国产乱码久久久久 | 亚洲一区二区三区miaa149 | 国产色婷婷精品综合在线手机播放 | 亚洲精品大全 | 亚洲国产婷婷 | 97手机电影网 | 国产一级片在线播放 | 亚洲精品一区二区三区新线路 | 丁香六月婷 | 亚洲黄污 | 麻豆视频免费入口 | 狠狠狠色丁香婷婷综合久久五月 | 日韩高清一 | 亚洲欧洲国产精品 | 国产系列 在线观看 | 成人高清av在线 | 欧洲一区二区在线观看 | 成人va视频 | 99精品欧美一区二区三区 | 毛片激情永久免费 | 黄色小视频在线观看免费 | 国产黄色片一级三级 | 97超碰人人在线 | a亚洲视频| 精品人人人人 | 欧美久久久久久久久久久久久 | av福利在线看 | 国产手机在线精品 | 国产手机视频精品 | 中文字幕av有码 | 久久久网页 | 男女激情麻豆 | 永久免费毛片 | 在线观看成人av | 成人9ⅰ免费影视网站 | av在线播放快速免费阴 | v片在线看 | 狠狠狠狠狠狠狠 | 91亚洲狠狠婷婷综合久久久 | 黄色三级在线看 | www.99av | 高清av中文字幕 | 又黄又网站 | 人人爽人人爽人人爽学生一级 | 成人黄色免费观看 | 亚洲综合婷婷 | 国产一级片免费播放 | 亚洲成人资源 | 日韩精品免费一区二区三区 | 国产女人免费看a级丨片 | 一级黄色毛片 | 日韩剧| 久久av免费电影 | 国产91精品看黄网站 | 四虎免费在线观看视频 | 国产免费叼嘿网站免费 | av在线免费不卡 | 久久久久麻豆v国产 | 黄色大片中国 | 欧美日韩在线免费视频 | 国产成人精品一区二区三区网站观看 | 99爱国产精品 | 超碰免费97 | 中文字幕第一页在线播放 | 日韩av午夜在线观看 | 婷婷av网 | 亚洲黄色一级视频 | 在线视频1卡二卡三卡 | 日韩专区一区二区 | 亚洲午夜精品一区二区三区电影院 | 久久久精品国产一区二区电影四季 | 日韩视频免费观看高清完整版在线 | 国产美女免费 | 精品在线二区 | 久久久久区 | av免费试看 | www.97色.com | 日韩极品在线 | www.色午夜 | 亚洲黄网站 | 国产高清 不卡 | 成人免费xxx在线观看 | 操操操日日日干干干 | 久久免费精品一区二区三区 | 免费在线观看日韩视频 | 99视频在线免费看 | 97国产精品一区二区 | 97av免费视频 | 国产一性一爱一乱一交 | 欧美激情xxxx性bbbb | 成年人网站免费观看 | 中文字幕 成人 | 五月婷综合 | 97理论片 | 日本激情动作片免费看 | 爱情影院aqdy鲁丝片二区 | 欧美地下肉体性派对 | 精品一区在线看 | 91av视频网 | 九九综合九九 | 亚洲精品白浆高清久久久久久 | 色网站视频 | 日韩v欧美v日本v亚洲v国产v | 超碰人人乐 | 黄色网在线播放 | 精品成人免费 | 久久久国产毛片 | 成人免费在线电影 | 国内精品视频一区二区三区八戒 | 久久这里只有精品视频99 | 日韩中文字幕免费在线观看 | 天天干com | 一二三区高清 | 国产一在线精品一区在线观看 | 丝袜美女在线观看 | 成人a视频片观看免费 | 国产热re99久久6国产精品 | 在线影视 一区 二区 三区 | 日日操操操 | 久久视频精品在线观看 | 精品国产诱惑 | 亚洲精品乱码久久久久久久久久 | 亚洲婷婷在线视频 | 亚洲欧美国产精品va在线观看 | 麻豆影视在线播放 | 欧美福利久久 | 色的网站在线观看 | 偷拍区另类综合在线 | 天天操天天添 | 亚洲精品 在线视频 | 97精品国产97久久久久久粉红 | 久久精品免费播放 | 中文在线字幕免费观看 | 香蕉视频国产在线观看 | 丁香久久综合 | 国产三级精品三级在线观看 | 爱爱av网| 91成人免费在线 | 91精品国产综合久久婷婷香蕉 | 亚洲精品高清视频 | 久久精品久久99 | 美女视频又黄又免费 | 毛片随便看 | 亚洲资源在线 | 99视频+国产日韩欧美 | 久草9视频 | 日韩有码在线观看视频 | 日韩免费视频线观看 | 激情网综合 | 日韩高清无线码2023 | 天天天干天天射天天天操 | 色综合狠狠干 | 伊人看片 | 免费观看国产精品视频 | 中文字幕在线观看一区 | 97在线观看免费观看高清 | 香蕉视频91 | 丁香婷婷久久久综合精品国产 | 香蕉视频在线网站 | 精品美女久久久久 | 黄污网 | 97国产一区二区 | 国产无吗一区二区三区在线欢 | 国产在线精 | 91一区二区三区久久久久国产乱 | 在线欧美中文字幕 | 日韩理论视频 | 国产一在线精品一区在线观看 | 欧美福利视频 | 亚洲成熟女人毛片在线 | 99久热在线精品视频观看 | 黄色小说在线免费观看 | 国产黑丝一区二区三区 | 大荫蒂欧美视频另类xxxx | 久久国产精品一国产精品 | 日本福利视频在线 | 国产123av | 国产精品aⅴ| 看毛片的网址 | 色婷婷激情网 | 欧美乱码精品一区二区 | 久草久热 | 成年人免费看片网站 | 不卡电影免费在线播放一区 | 成年人视频在线观看免费 | 伊人小视频 | 亚洲精品一区二区三区新线路 | 九九av| 国产精品 日韩 | 五月婷在线观看 | 国产不卡一区二区视频 | 亚洲国产日韩欧美 | 中文字幕中文字幕中文字幕 | 国模一区二区三区四区 | 伊人国产视频 | www.夜夜爱 | 中文字幕在线视频一区 | 国产免费观看av | 欧美日韩中文在线视频 | 不卡av在线 | 永久免费的啪啪网站免费观看浪潮 | 国产自产在线视频 | 日韩av视屏 | 韩日精品中文字幕 | 99精彩视频在线观看免费 | 欧美视频二区 | 久久69av | 日韩二区在线 | 成人夜晚看av | 国产一区在线不卡 | 在线a人v观看视频 | 在线观看视频中文字幕 | 91.精品高清在线观看 | 狠狠色丁香久久综合网 | 米奇四色影视 | ,午夜性刺激免费看视频 | 中文字幕精品一区 | 欧美坐爱视频 | 国产91丝袜在线播放动漫 | 国产精品国产三级国产 | 欧美日韩中文在线视频 | 99精品久久久久久久久久综合 | 国产精品九九九九九九 | 992tv人人网tv亚洲精品 | 日韩欧美视频在线 | 99爱在线 | 美女网站视频免费都是黄 | 激情综合亚洲 | 亚洲乱码一区 | 成年人在线看片 | 久久99精品一区二区三区三区 | 一级片免费观看 | 成人午夜电影在线 | 精品国产伦一区二区三区观看方式 | 国产97在线播放 | 亚洲国产中文字幕在线 | 四虎成人免费影院 | 日韩中文字幕在线看 | 在线观看国产亚洲 | 国产在线久草 | 国产黄色大片免费看 | 亚洲视频免费 | 人人澡人人添人人爽一区二区 | 国产精品一区二区久久精品爱微奶 | 欧美a在线免费观看 | 中文在线8新资源库 | 欧美一级片免费播放 | 97精品国产一二三产区 | 日日爽 | 国产不卡视频在线播放 | 最新中文字幕在线播放 | 欧美男女爱爱视频 | 99视频在线精品国自产拍免费观看 | 国产伦精品一区二区三区照片91 | 久久综合九色综合久久久精品综合 | 在线欧美中文字幕 | 久久精品2| 狠狠gao| 国产中文字幕视频在线 | 日韩在线观看视频在线 | 欧美久久久久久久久久久久 | 男女免费视频观看 | 色视频网页 | 色99视频 | www五月 | 手机av电影在线观看 | 精品国内自产拍在线观看视频 | 欧美亚洲国产精品久久高清浪潮 | 中文字幕av免费 | 精品影院一区二区久久久 | 午夜av色 | 日韩美女黄色片 | 五月婷婷深开心 | 免费a网站 | 日韩毛片在线免费观看 | 中文字幕永久免费 | 日日夜夜精品免费视频 | 亚洲永久精品国产 | 99久久精品国产一区二区成人 | 五月天欧美精品 | 欧美成人精品欧美一级乱 | 日韩中文字幕免费在线观看 | 欧美激情精品久久久久久免费印度 | 色综合久久悠悠 | 日韩大片在线观看 | 久久久久久高清 | 亚洲国产精品一区二区尤物区 | 九九热久久免费视频 | 天天操夜夜摸 | 九九热免费视频在线观看 | 国产免费视频一区二区裸体 | 国产免费av一区二区三区 | 亚洲精品国精品久久99热 | 成人18视频| 久久成熟 | 91精品国自产在线 | av在线精品 | 免费在线一区二区 | 国内精品久久久久影院一蜜桃 | 亚洲片在线观看 | 久久综合婷婷国产二区高清 | 国产午夜精品一区二区三区欧美 | 五月天天av| 免费麻豆视频 | 精品国产1区 | 国产亚洲在 | 中文字幕有码在线观看 | 91免费国产在线观看 | www.亚洲精品视频 | 亚洲视频电影在线 | 亚洲乱码中文字幕综合 | 成人黄色影片在线 | 人人狠狠综合久久亚洲 | 久久久久免费精品视频 | 日韩xxx视频 | 久草视频资源 | 久久午夜电影院 | 国产无套一区二区三区久久 | 色婷婷综合久久久久中文字幕1 | 国产精品高清一区二区三区 | 日本精品一 | 天天伊人网 | 国产精品入口麻豆www | 日韩亚洲欧美中文字幕 | 成人av资源网站 | 国产男女无遮挡猛进猛出在线观看 | 精品国产理论片 | 久久久久久久久毛片精品 | 超碰97公开 | 久草精品视频 | 美女视频黄的免费的 | 成人一区电影 | 日韩美女一级片 | 国产精品 亚洲精品 | 欧美日韩国产精品一区二区亚洲 | 美女久久久 | 午夜久久久久 | 91精品国产九九九久久久亚洲 | 人人干网站 | 天天干,天天操,天天射 | 婷婷成人综合 | 免费一区在线 | 成年人三级网站 | 久草视频手机在线 | 午夜电影一区 | 69国产精品视频免费观看 | 日韩精品一区二区三区免费观看视频 | 国产一区二区三区四区在线 | 国产精品一区免费观看 | 国产麻豆精品传媒av国产下载 | 亚洲午夜av | 久操视频在线 | 国产九色在线播放九色 | 精品中文字幕视频 | 免费观看性生活大片3 | 日本精品久久久久影院 | 久久免费视频3 | 欧美成年黄网站色视频 | 在线 精品 国产 | 免费久久精品视频 | 在线视频你懂 | 808电影| 免费色av| 黄污污网站 | 天天色天天综合 | 国产做aⅴ在线视频播放 | www.伊人色.com | 91在线观看欧美日韩 | 91高清在线| 久久国产精品久久w女人spa | 欧美精品一区二区在线观看 | 92国产精品久久久久首页 | 国产一区精品在线观看 | 色综合网| 日韩美精品视频 | 99精品热视频 | 免费视频久久久久久久 | 黄色在线免费观看网站 | 亚洲性xxxx| 免费观看黄 | 天天综合中文 | 久久国产一区二区三区 | 亚洲国产成人久久综合 | 成 人 黄 色 片 在线播放 | av九九九 | 久草在线这里只有精品 | 人人爽人人爽人人爽人人爽 | 国产999 | 久久久久久久久精 | 国产精品成人一区二区 | 视频在线观看入口黄最新永久免费国产 | 日韩av高潮| 香蕉久草在线 | 久草在线资源观看 | 久久这里精品视频 | 色视频网址 | 丁香花在线视频观看免费 | 国产日韩精品一区二区三区在线 | 亚洲婷婷伊人 | 久久精品波多野结衣 | 久久免费视频99 | 天天射狠狠干 | 99爱国产精品 | 天天干夜夜爱 | 色婷婷色 | 久久丝袜视频 | 伊人色**天天综合婷婷 | 国产在线色站 | 在线免费观看黄色 | 国产精品久久久久久久久久久免费 | 国产精品美女久久久久久网站 | 人人看人人艹 | 91精品在线看 | 色网站在线免费观看 | 亚洲伊人天堂 | 精品国产观看 | 久久这里只有精品9 | 成人免费影院 | 天天爽天天做 | 激情欧美丁香 | 亚洲综合在线五月天 | 欧美精品亚洲二区 | 五月婷婷综合在线视频 | 91喷水| 成人午夜电影久久影院 | 国产黄色精品 | 婷婷久月| 免费视频三区 | 久久成人人人人精品欧 | 国产日韩中文字幕 | 久久这里只精品 | 午夜性福利| 欧美午夜精品久久久久久浪潮 | 成 人 黄 色 片 在线播放 | 日韩精品久久久久久中文字幕8 | 99久久久久久国产精品 | 日韩精品一区二区三区中文字幕 | 狠狠久久 | 亚洲人天堂 | 99婷婷| 天天干夜夜想 | 97视频免费在线看 | 黄色大全免费网站 | 久久综合成人网 | 亚洲久在线| 天天综合网久久综合网 | 欧美视频在线观看免费网址 | 国产精品亚洲片夜色在线 | 激情综合亚洲精品 | 国产中文a | 97人人模人人爽人人喊网 | 一本色道久久综合亚洲二区三区 | 九九九九精品 | 午夜国产一区二区三区四区 | 国产一区二区三区 在线 | 99精品久久久久久久 | 精品国产一区二区三区男人吃奶 | 午夜美女网站 | 国产一区成人 | 探花视频在线观看+在线播放 | 亚洲精品国产麻豆 | 中文字幕在线网址 | av电影在线播放 | 免费成人av在线 | 97在线视频免费看 | 成人网444ppp | 国产视频精品久久 | 亚洲黄色免费在线 | 久艹在线免费观看 | 婷婷99| 欧美在线观看禁18 | 91九色在线观看 | 黄网站免费久久 | 久久久精品成人 | 国产女人40精品一区毛片视频 | 天天想夜夜操 | 97理论片 | 日韩.com| 免费观看一区二区三区视频 | 国产男女爽爽爽免费视频 | 国内精品久久久久久中文字幕 | 在线看日韩| 国产精品一区二区免费视频 | 国产免费大片 | 欧洲视频一区 | 午夜美女福利 | 91成人精品在线 | 国产香蕉视频在线播放 | 久久九九影视 | 国产高清在线a视频大全 | 综合在线色 | 国产中文字幕视频在线观看 | 欧美一区二区日韩一区二区 | www.午夜 | 久久国语露脸国产精品电影 | 国产精品视频内 | 天天玩天天操天天射 | 成人免费在线观看入口 | 国产亚洲无 | 不卡中文字幕在线 | 国产破处精品 | 日本黄色免费网站 | 中文字幕在线免费 | 久久久视频在线 | 丝袜美女在线观看 | 久久精品xxx | 亚洲国产美女久久久久 | 看v片| 91丨九色丨国产在线 | 日韩亚洲国产精品 | 日本久久成人中文字幕电影 | 亚洲专区在线视频 | 天天操天天干天天 | 在线综合 亚洲 欧美在线视频 | 久久久精品福利视频 | 精品久久久久久亚洲综合网站 | 激情五月激情综合网 | 亚洲另类xxxx | 国产精品久免费的黄网站 | 91麻豆文化传媒在线观看 | 岛国一区在线 | 五月婷婷丁香 | 久久99在线 | 精品视频久久 | 91自拍视频在线观看 | 久久国产精品色婷婷 | 国产精品久久久久婷婷二区次 | 中文字幕电影高清在线观看 | 人人澡视频 | 国内精品久久久久影院优 | 国产美女视频一区 | 在线不卡的av | 亚洲男男gⅴgay双龙 | 国产一区二区三区免费观看视频 | 久热香蕉视频 | 五月婷婷,六月丁香 |