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

基于JWT的RuoYi開發(fā)框架與EMQX的系統(tǒng)集成方法

開發(fā) 架構(gòu)
我們使用JwtAccessTokenConverter來生成Jwt Token,JwtAccessTokenConverter默認(rèn)使用的Signer是MacSigner,而MacSigner默認(rèn)的算法是HMACSHA256。下面這個(gè)地方配置的Signkey一定要與上面配置EMQX的JWT認(rèn)證時(shí)的Secret一致,這樣就可以讓EMQX驗(yàn)證Token的真假。

背景

RuoYi是一款基于Spring Boot、Spring Security和MyBatis的快速開發(fā)框架,它目前在中后臺(tái)管理系統(tǒng)開發(fā)領(lǐng)域擁有大量的使用者。但是它當(dāng)前缺少對(duì)websocket協(xié)議雙工通信信道的支持,即長(zhǎng)鏈接管理這塊的功能比較弱。導(dǎo)致像實(shí)時(shí)通知(后臺(tái)服務(wù)與前端的消息推送,異步通知),實(shí)時(shí)數(shù)據(jù)可視化(后端獲取數(shù)據(jù)并推送到前端)等功能不好實(shí)現(xiàn)。本文介紹如果結(jié)合第三方消息代理服務(wù)器EMQX實(shí)現(xiàn)上述功能。

準(zhǔn)備

Docker安裝EMQX

docker pull emqx/emqx:5.0.21
docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx:5.0.21

EMQX訪問配置

登錄EMQX后臺(tái),點(diǎn)擊菜單Access Control ->Authentication。

新增配置,選擇JWT,因?yàn)镽uoYi的框架使用的是JWT,這個(gè)地方就是讓EMQX的認(rèn)證方式和RuoYi的一致,這樣RuoYi返回的token,我們可以直接通過它來調(diào)用EMQX的restful接口,實(shí)現(xiàn)發(fā)送消息。

新增配置認(rèn)證

登錄EMQX管理后臺(tái),配置認(rèn)證

其中JWT from這個(gè)地方我們選擇username,然后算法根據(jù)你的RuoYi框架實(shí)現(xiàn)的token的算法,這個(gè)地方我們使用的是hmac.其他的實(shí)踐可以查看這https://www.emqx.io/docs/en/v5.0/access-control/authn/jwt.html#configure-with-dashboard。

配置RuoYi的token生成

我們使用JwtAccessTokenConverter來生成jwt token,JwtAccessTokenConverter默認(rèn)使用的signer是MacSigner,而MacSigner默認(rèn)的算法是HMACSHA256。下面這個(gè)地方配置的signkey一定要與上面配置EMQX的JWT認(rèn)證時(shí)的Secret一致,這樣就可以讓EMQX驗(yàn)證token的真假。

@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
    JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
    converter.setSigningKey("mytokenkey");// token key
    converter.setAccessTokenConverter(new NewTokenConverter());
    return converter;
}

JwtAccessTokenConverter的signer

我們想擴(kuò)展ken的額外信息,便可以繼承AccessTokenConverter,寫一個(gè)新的。在這個(gè)轉(zhuǎn)化器中,我們可以加入額外的屬性identity,這樣token里面就包含了這些有用的信息。

package com.ruoyi.framework.auth.config.tokenconvert;

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2Request;
import org.springframework.security.oauth2.provider.token.AccessTokenConverter;
import org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter;
import org.springframework.security.oauth2.provider.token.UserAuthenticationConverter;

import java.util.*;

public class NewTokenConverter implements AccessTokenConverter {
  private UserAuthenticationConverter userTokenConverter = new DefaultUserAuthenticationConverter();
  private boolean includeGrantType;
  private String scopeAttribute = "scope";
  private String clientIdAttribute = "client_id";

  public NewTokenConverter() {
  }

  public void setUserTokenConverter(UserAuthenticationConverter userTokenConverter) {
    this.userTokenConverter = userTokenConverter;
  }

  public void setIncludeGrantType(boolean includeGrantType) {
    this.includeGrantType = includeGrantType;
  }

  public void setScopeAttribute(String scopeAttribute) {
    this.scopeAttribute = scopeAttribute;
  }

  public void setClientIdAttribute(String clientIdAttribute) {
    this.clientIdAttribute = clientIdAttribute;
  }

  public Map<String, ?> convertAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
    Map<String, Object> response = new HashMap();
    OAuth2Request clientToken = authentication.getOAuth2Request();
    if (!authentication.isClientOnly()) {
      response.putAll(this.userTokenConverter.convertUserAuthentication(authentication.getUserAuthentication()));
    } else if (clientToken.getAuthorities() != null && !clientToken.getAuthorities().isEmpty()) {
      response.put("authorities", AuthorityUtils.authorityListToSet(clientToken.getAuthorities()));
    }

    if (token.getScope() != null) {
      response.put(this.scopeAttribute, token.getScope());
    }

    if (token.getAdditionalInformation().containsKey("jti")) {
      response.put("jti", token.getAdditionalInformation().get("jti"));
    }

    if (token.getExpiration() != null) {
      response.put("exp", token.getExpiration().getTime() / 1000L);
    }
    if (authentication.getName()!=null) {
      response.put("identity", authentication.getName());
    }

    if (this.includeGrantType && authentication.getOAuth2Request().getGrantType() != null) {
      response.put("grant_type", authentication.getOAuth2Request().getGrantType());
    }

    response.putAll(token.getAdditionalInformation());
    response.put(this.clientIdAttribute, clientToken.getClientId());
    if (clientToken.getResourceIds() != null && !clientToken.getResourceIds().isEmpty()) {
      response.put("aud", clientToken.getResourceIds());
    }

    return response;
  }

  public OAuth2AccessToken extractAccessToken(String value, Map<String, ?> map) {
    DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken(value);
    Map<String, Object> info = new HashMap(map);
    info.remove("exp");
    info.remove("aud");
    info.remove(this.clientIdAttribute);
    info.remove(this.scopeAttribute);
    if (map.containsKey("exp")) {
      token.setExpiration(new Date((Long)map.get("exp") * 1000L));
    }

    if (map.containsKey("jti")) {
      info.put("jti", map.get("jti"));
    }

    token.setScope(this.extractScope(map));
    token.setAdditionalInformation(info);
    return token;
  }

  public OAuth2Authentication extractAuthentication(Map<String, ?> map) {
    Map<String, String> parameters = new HashMap();
    Set<String> scope = this.extractScope(map);
    Authentication user = this.userTokenConverter.extractAuthentication(map);
    String clientId = (String)map.get(this.clientIdAttribute);
    parameters.put(this.clientIdAttribute, clientId);
    if (this.includeGrantType && map.containsKey("grant_type")) {
      parameters.put("grant_type", (String)map.get("grant_type"));
    }

    Set<String> resourceIds = new LinkedHashSet((Collection)(map.containsKey("aud") ? this.getAudience(map) : Collections.emptySet()));
    Collection<? extends GrantedAuthority> authorities = null;
    if (user == null && map.containsKey("authorities")) {
      String[] roles = (String[])((Collection)map.get("authorities")).toArray(new String[0]);
      authorities = AuthorityUtils.createAuthorityList(roles);
    }

    OAuth2Request request = new OAuth2Request(parameters, clientId, authorities, true, scope, resourceIds, (String)null, (Set)null, (Map)null);
    return new OAuth2Authentication(request, user);
  }

  private Collection<String> getAudience(Map<String, ?> map) {
    Object auds = map.get("aud");
    if (auds instanceof Collection) {
      Collection<String> result = (Collection)auds;
      return result;
    } else {
      return Collections.singleton((String)auds);
    }
  }

  private Set<String> extractScope(Map<String, ?> map) {
    Set<String> scope = Collections.emptySet();
    if (map.containsKey(this.scopeAttribute)) {
      Object scopeObj = map.get(this.scopeAttribute);
      if (String.class.isInstance(scopeObj)) {
        scope = new LinkedHashSet(Arrays.asList(((String)String.class.cast(scopeObj)).split(" ")));
      } else if (Collection.class.isAssignableFrom(scopeObj.getClass())) {
        Collection<String> scopeColl = (Collection)scopeObj;
        scope = new LinkedHashSet(scopeColl);
      }
    }

    return (Set)scope;
  }
}

客戶端連接

npm install --save mqtt
import mqtt from 'mqtt'
createWebSocket() {

  const clientId = 'mqttjs_' + Math.random().toString(16).substr(2, 8)

  const host = process.env.VUE_APP_WEB_SOCKET

  const options = {
    keepalive: 60,
    clientId: clientId,
    username:getToken(),
    protocolId: 'MQTT',
    protocolVersion: 4,
    clean: true,
    reconnectPeriod: 1000,
    connectTimeout: 30 * 1000,
    will: {
      topic: 'WillMsg',
      payload: 'Connection Closed abnormally..!',
      qos: 0,
      retain: false
    },
  }

  console.log('Connecting mqtt client')

  this.ws = mqtt.connect(host, options)

  this.ws.on('error', (err) => {
    console.log('Connection error: ', err)
    this.ws.end()
  })

  this.ws.on('reconnect', () => {
    console.log('Reconnecting...')
  })

  this.ws.on('connect', () => {
    console.log('Client connected:' + clientId)
    // Subscribe
    this.ws.subscribe(store.getters.topic, { qos: 0 })
  })

  // Received
  this.ws.on('message', (topic, message, packet) => {
    console.log('Received Message: ' + message.toString() + '\nOn topic: ' + topic)
  })
},

測(cè)試

我們測(cè)試收到了消息提示,同時(shí)打開console,看到我們連接成功了。

收到消息

連接log

參考鏈接

https://www.emqx.com/en/blog/connect-to-mqtt-broker-with-websocket。

責(zé)任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2023-05-16 08:27:12

2009-07-14 13:08:55

WebWork與Spr

2023-03-14 18:06:07

flink數(shù)字集成

2022-09-06 15:00:09

機(jī)器學(xué)習(xí)集成數(shù)據(jù)集

2022-09-15 23:58:51

機(jī)器學(xué)習(xí)集成數(shù)據(jù)

2025-01-03 09:17:26

JavaSpringBoot

2013-11-13 13:32:36

Linux系統(tǒng)管理NetApp存儲(chǔ)

2019-05-16 09:28:12

集成學(xué)習(xí)機(jī)器學(xué)習(xí)模型

2018-11-16 15:42:27

網(wǎng)絡(luò)系統(tǒng)集成網(wǎng)絡(luò)技術(shù)網(wǎng)絡(luò)

2013-07-04 16:48:26

AndroidJ2ee

2009-06-16 11:13:38

Javadoc生成方法Javadoc

2012-12-03 13:54:15

IBMdW

2022-08-15 21:26:09

物聯(lián)網(wǎng)智能建筑系統(tǒng)集成

2021-06-22 18:00:09

微服務(wù)架構(gòu)系統(tǒng)

2018-04-16 09:50:38

ERP CRM

2017-12-29 15:16:49

Parcel集成方式

2023-12-09 17:04:26

nDPIHyperscan

2025-02-27 00:00:30

SpringJava方式

2022-10-08 06:30:23

機(jī)器學(xué)習(xí)人工智能工具

2023-11-13 15:01:28

機(jī)器學(xué)習(xí)
點(diǎn)贊
收藏

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

日韩精品成人在线| 精品人妻一区二区三区免费| 黄视频在线播放| 日韩av在线播放中文字幕| 一区二区三区视频免费在线观看| 羞羞的视频在线| 国产精品69xx| 久久伊人中文字幕| 国产啪精品视频网站| 免费一级黄色大片| 久操精品在线| 日韩一区二区三区四区| av黄色在线网站| 日本a级在线| 成a人片国产精品| 国产美女高潮久久白浆| 国产精品99久久久久久成人| 91免费精品国偷自产在线在线| 日韩欧亚中文在线| 精品少妇人妻av一区二区| 四虎电影院在线观看| 极品少妇xxxx偷拍精品少妇| 51午夜精品视频| 538任你躁在线精品视频网站| 天天做夜夜做人人爱精品 | 日韩精品免费综合视频在线播放| 看欧美ab黄色大片视频免费| free性欧美| 中文字幕中文字幕中文字幕亚洲无线| 国产精品日韩一区二区| 国产又黄又猛又爽| 热久久久久久久| 欧美亚洲激情在线| 精品无码久久久久久久久| 欧美r级电影| 亚洲视频视频在线| 老司机午夜免费福利| 国产95亚洲| 欧美三级韩国三级日本三斤| 欧美国产激情视频| 成人bbav| 亚洲国产精品综合小说图片区| 亚洲精品在线免费| 爱爱爱免费视频在线观看| 91蜜桃免费观看视频| 国产99午夜精品一区二区三区| 中文字幕乱码一区二区| 久久人人精品| 91精品国产高清自在线看超| 国产一级片视频| 午夜精品国产| 欧美成人午夜免费视在线看片| 国产主播av在线| 精品国产91乱码一区二区三区四区 | 久无码久无码av无码| 91香蕉在线观看| 亚洲欧美激情视频在线观看一区二区三区| 国产综合 伊人色| 日批视频免费播放| av毛片久久久久**hd| 国产一区二区三区高清| 人妻中文字幕一区| 91免费视频大全| 久久人人九九| 天堂中文在线8| 久久天天做天天爱综合色| 国精产品99永久一区一区| 日本免费一区视频| 97久久超碰国产精品| 久久精品ww人人做人人爽| 欧美巨乳在线| 国产精品久久久久久久久久久免费看| 亚洲视频sss| 岛国成人毛片| 一区二区三区免费观看| 日韩成人三级视频| 夜鲁夜鲁夜鲁视频在线播放| 色偷偷成人一区二区三区91| 蜜桃免费在线视频| 国产精品一区二区美女视频免费看| 欧美一区二区三区日韩| 国产午夜在线一区二区三区| 久久夜色电影| 国产一区二区三区欧美| 蜜桃av.com| 亚洲精品在线观看91| 欧美高清视频在线观看| 欧美成人精品欧美一级乱黄| 国产精品毛片在线| 国产精品麻豆va在线播放| 96日本xxxxxⅹxxx17| 成人午夜伦理影院| 品久久久久久久久久96高清| 好男人免费精品视频| 亚洲欧洲成人自拍| 中文字幕一区二区三区四区五区六区 | 国产a∨精品一区二区三区仙踪林| 久久国产日本精品| 成人网在线免费观看| 免费av网站观看| 中文字幕久久午夜不卡| 国产一线二线三线女| 三上悠亚亚洲一区| 欧美电视剧在线看免费| 成年人免费观看视频网站| 日韩精品网站| 国内精品久久久久久| 亚洲无码久久久久| 92国产精品观看| 只有这里有精品| 国模套图日韩精品一区二区| 欧美一区二区免费观在线| 97人妻精品一区二区免费| 亚洲蜜桃视频| 国产精品第3页| 欧美 日韩 国产 在线| 中文字幕欧美日本乱码一线二线| www.男人天堂网| 99re久久| 亚洲免费视频一区二区| 豆国产97在线 | 亚洲| 日韩高清在线电影| 精品国产免费人成电影在线观... 精品国产免费久久久久久尖叫 | 免费成人美女在线观看| 精品久久久久久中文字幕动漫| 免费黄色网页在线观看| 欧洲一区二区三区在线| japanese在线观看| 欧美va天堂在线| 国产欧美韩国高清| 四虎影院在线域名免费观看| 亚洲高清视频在线| 手机看片国产精品| 欧美岛国激情| 国产精品视频资源| 欧美孕妇孕交xxⅹ孕妇交| 亚洲香蕉伊在人在线观| 一级黄色免费毛片| 性xxxx欧美老肥妇牲乱| 国产精品久久久久久久久久久不卡 | 欧美日韩黄色网| 日韩av不卡在线观看| 久久久久久a亚洲欧洲aⅴ| 国产后进白嫩翘臀在线观看视频| 在线成人av网站| 蜜桃av.com| 精品中文字幕一区二区| 亚洲一区二区三区四区中文| 欧美色片在线观看| 亚洲天堂免费视频| 樱花视频在线免费观看| 久久麻豆一区二区| 国产一级片黄色| 精品freesex老太交| 国产不卡在线观看| 国产对白叫床清晰在线播放| 色88888久久久久久影院野外| 五级黄高潮片90分钟视频| 亚洲欧美日韩国产综合精品二区 | 欧美禁忌电影| 日韩免费在线播放| а天堂8中文最新版在线官网| 欧美中文字幕一二三区视频| 怡红院一区二区三区| 免费av网站大全久久| 亚洲午夜精品福利| 久久国产精品免费一区二区三区| 另类天堂视频在线观看| 午夜精品久久久久久久91蜜桃| 亚洲一区二区三区四区中文字幕| 在线中文字日产幕| 国产精品一级| 天堂资源在线亚洲资源| 成人97精品毛片免费看| 久久久免费精品| 日本大臀精品| 欧美探花视频资源| 久久精品视频免费在线观看| 国产99精品国产| 久久综合九色综合88i| 蜜臀91精品国产高清在线观看| 国产精品女人网站| 深夜国产在线播放| 亚洲欧美第一页| 91av久久久| 亚洲制服欧美中文字幕中文字幕| 天天插天天射天天干| 青青草一区二区三区| 免费的av在线| 亚洲人亚洲人色久| 成人免费网视频| 成人免费网站观看| 最好看的2019年中文视频| 亚洲成人黄色片| 91成人网在线| 精品国产乱码久久久久久鸭王1| proumb性欧美在线观看| 国产小视频精品| 激情综合中文娱乐网| 亚洲春色在线| 欧美电影在线观看完整版| 国产精品视频自拍| 超碰99在线| 国产一区二区美女视频| 一级久久久久久久| 狠狠做深爱婷婷久久综合一区| 黄色一级片一级片| 91色综合久久久久婷婷| 中文 日韩 欧美| 久久欧美肥婆一二区| 老司机激情视频| 国产精品欧美三级在线观看| 成人黄色片视频网站| 久久精品嫩草影院| 91成人在线播放| 蜜芽在线免费观看| 亚洲欧美在线免费观看| www.狠狠干| 欧美日韩第一区日日骚| 亚洲黄色免费观看| 亚洲福利一区二区| 欧美成人片在线观看| 国产精品久久久久久久蜜臀| 中文字幕日韩三级片| 国产高清不卡二三区| 手机看片一级片| 久久亚洲精品伦理| 日本在线xxx| 欧美区国产区| 日本一二三区视频在线| 日本一区二区免费高清| 日本一区高清在线视频| 欧美亚洲国产日韩| 国产精品手机在线| 6080成人| 成人高清在线观看| 91成人福利| 成人av片网址| 亚洲高清在线一区| 444亚洲人体| 国产一区二区三区亚洲综合| 欧美在线激情视频| 涩涩av在线| 欧美性受xxxx黑人猛交| 国产传媒在线| 欧美在线视频免费| 一区二区乱码| 国产国语videosex另类| 欧美极品免费| 国产精品久久久久久超碰| 日日夜夜天天综合| 国产精品久久久久久久久影视| 婷婷综合六月| 国产日产久久高清欧美一区| 欧美美女福利视频| 亚洲www视频| 伊人久久大香线蕉av超碰| av日韩免费电影| 久久夜色精品国产噜噜av小说| 国产欧美日韩综合一区在线观看| 成人性生交大片免费看中文视频| 国产精品一区二区三区免费观看| 亚洲高清在线一区| 久久久久久久久久码影片| 九热爱视频精品视频| 日韩亚洲一区在线播放| 婷婷精品进入| 国产av熟女一区二区三区| 激情久久婷婷| 久久精品免费一区二区| 免费成人在线观看视频| 免费看的av网站| 9色porny自拍视频一区二区| 四虎永久免费影院| 中文字幕第一区二区| 欧美成人综合色| 精品欧美aⅴ在线网站 | 欧美一级片在线| 欧美自拍偷拍第一页| 亚洲毛片一区二区| 日韩伦理在线电影| 久久久久久91香蕉国产| 中文不卡1区2区3区| 国产精品美女主播在线观看纯欲| 91精品麻豆| 国内一区在线| 成人3d动漫在线观看| 青青在线视频免费观看| 男女av一区三区二区色多| 国产又粗又长又爽又黄的视频| 99久久精品免费观看| 国产性猛交xx乱| 亚洲伊人色欲综合网| 中文字幕xxxx| 欧美大黄免费观看| 久久天堂电影| 欧美日韩国产二区| 日本一区二区电影| 国产精品久久久久久久久婷婷| 国产精品嫩模av在线| 成人短视频在线观看免费| 老牛国产精品一区的观看方式| 中文字幕一区二区在线观看视频| 99久久精品国产网站| 99自拍视频在线| 欧美性高潮床叫视频| 99热这里只有精品在线| 亚洲区在线播放| 牛牛在线精品视频| 国产综合视频在线观看| 欧美**字幕| 男女日批视频在线观看| 国产在线国偷精品免费看| 人妻大战黑人白浆狂泄| 亚洲一区二区四区蜜桃| 91亚洲精品国偷拍自产在线观看 | 欧美在线三区| 日韩在线第三页| 97精品超碰一区二区三区| 五月天丁香激情| 欧美日韩国产综合草草| 免费国产在线观看| 97视频网站入口| 北条麻妃在线一区二区免费播放 | 国产高清在线精品一区二区三区| 青青草综合网| 国产成人无码av在线播放dvd| 成人午夜视频网站| 久久黄色小视频| 911精品国产一区二区在线| 国产视频精选在线| 日韩av理论片| 欧洲亚洲视频| 男女视频网站在线观看| 国产91精品欧美| 国内偷拍精品视频| 制服丝袜国产精品| 日本网站在线免费观看视频| 国产精品wwww| 精品欧美久久| 国产视频一区二区视频| 国产视频亚洲色图| 区一区二在线观看| 精品一区二区三区四区| 麻豆免费在线| 精品国产福利| 久久国产一二区| 熟女高潮一区二区三区| 一本色道**综合亚洲精品蜜桃冫| 日韩av成人| 日韩免费观看在线观看| 国产91精品对白在线播放| 日日碰狠狠丁香久燥| 国产女同互慰高潮91漫画| 激情网站在线观看| 色偷偷888欧美精品久久久| 欧美电影在线观看网站| 一本—道久久a久久精品蜜桃| 久久99这里只有精品| 在线看的片片片免费| 欧美一区二区三区思思人| 日本电影在线观看| 国产欧美日韩视频一区二区三区| 亚洲巨乳在线| 国产美女免费网站| 欧美三级韩国三级日本三斤| 黄色一级大片在线免费看产| 91九色蝌蚪成人| 伊人成年综合电影网| 噜噜噜在线视频| 精品视频一区二区不卡| 岛国成人毛片| 久久综合一区| 麻豆极品一区二区三区| 欧美日韩在线视频免费| 亚洲精品720p| 成人h在线观看| 8x8x华人在线| 91农村精品一区二区在线| 伊人久久成人网| 欧美激情视频免费观看| 亚洲国产精品嫩草影院久久av| 91在线视频观看免费| 亚洲老妇xxxxxx| 无码国产精品一区二区免费16| 国产成人久久久精品一区| 99国产**精品****| 先锋资源av在线| 欧美日韩综合色| 国产极品人妖在线观看| 亚洲 国产 欧美一区| 国产99精品国产| 波多野结衣绝顶大高潮| 欧美日韩xxxxx| 国产91精品对白在线播放| 日本黄色www| 色系网站成人免费| 国产精品一区hongkong| 一区二区欧美日韩| 91亚洲精品久久久蜜桃|