最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot+netty-socketio實(shí)現(xiàn)服務(wù)器端消息推送

 更新時(shí)間:2021年03月17日 10:48:00   作者:ATwill...  
這篇文章主要介紹了SpringBoot+netty-socketio實(shí)現(xiàn)服務(wù)器端消息推送,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

首先:因?yàn)楣ぷ餍枰枰獙?duì)接socket.io框架對(duì)接,所以目前只能使用netty-socketio。websocket是不支持對(duì)接socket.io框架的。

netty-socketio顧名思義他是一個(gè)底層基于netty'實(shí)現(xiàn)的socket。

在springboot項(xiàng)目中的集成,請(qǐng)看下面的代碼

maven依賴

<dependency>
 <groupId>com.corundumstudio.socketio</groupId>
 <artifactId>netty-socketio</artifactId>
 <version>1.7.11</version>
</dependency>

 下面就是代碼了

首先是配置參數(shù)

#socketio配置
socketio:
 host: localhost
 port: 9099
 # 設(shè)置最大每幀處理數(shù)據(jù)的長(zhǎng)度,防止他人利用大數(shù)據(jù)來(lái)攻擊服務(wù)器
 maxFramePayloadLength: 1048576
 # 設(shè)置http交互最大內(nèi)容長(zhǎng)度
 maxHttpContentLength: 1048576
 # socket連接數(shù)大小(如只監(jiān)聽一個(gè)端口boss線程組為1即可)
 bossCount: 1
 workCount: 100
 allowCustomRequests: true
 # 協(xié)議升級(jí)超時(shí)時(shí)間(毫秒),默認(rèn)10秒。HTTP握手升級(jí)為ws協(xié)議超時(shí)時(shí)間
 upgradeTimeout: 1000000
 # Ping消息超時(shí)時(shí)間(毫秒),默認(rèn)60秒,這個(gè)時(shí)間間隔內(nèi)沒有接收到心跳消息就會(huì)發(fā)送超時(shí)事件
 pingTimeout: 6000000
 # Ping消息間隔(毫秒),默認(rèn)25秒??蛻舳讼蚍?wù)器發(fā)送一條心跳消息間隔
 pingInterval: 25000

上面的注釋寫的很清楚。下面是config代碼

import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketConfig;
import com.corundumstudio.socketio.SocketIOServer;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * kcm
 */
@Component
public class PushServer implements InitializingBean {

  @Autowired
  private EventListenner eventListenner;

  @Value("${socketio.port}")
  private int serverPort;

  @Value("${socketio.host}")
  private String serverHost;

  @Value("${socketio.bossCount}")
  private int bossCount;

  @Value("${socketio.workCount}")
  private int workCount;

  @Value("${socketio.allowCustomRequests}")
  private boolean allowCustomRequests;

  @Value("${socketio.upgradeTimeout}")
  private int upgradeTimeout;

  @Value("${socketio.pingTimeout}")
  private int pingTimeout;

  @Value("${socketio.pingInterval}")
  private int pingInterval;

  @Override
  public void afterPropertiesSet() throws Exception {
    Configuration config = new Configuration();
    config.setPort(serverPort);
    config.setHostname(serverHost);
    config.setBossThreads(bossCount);
    config.setWorkerThreads(workCount);
    config.setAllowCustomRequests(allowCustomRequests);
    config.setUpgradeTimeout(upgradeTimeout);
    config.setPingTimeout(pingTimeout);
    config.setPingInterval(pingInterval);

    SocketConfig socketConfig = new SocketConfig();
    socketConfig.setReuseAddress(true);
    socketConfig.setTcpNoDelay(true);
    socketConfig.setSoLinger(0);
    config.setSocketConfig(socketConfig);

    SocketIOServer server = new SocketIOServer(config);
    server.addListeners(eventListenner);
    server.start();
    System.out.println("啟動(dòng)正常");
  }
}

在就是監(jiān)聽代碼

import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.annotation.OnConnect;
import com.corundumstudio.socketio.annotation.OnDisconnect;
import com.corundumstudio.socketio.annotation.OnEvent;
import org.apache.commons.lang3.StringUtils;
import org.bangying.auth.JwtSupport;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.UUID;

@Component
public class EventListenner {
  @Resource
  private ClientCache clientCache;

  @Resource
  private JwtSupport jwtSupport;

  /**
   * 客戶端連接
   *
   * @param client
   */
  @OnConnect
  public void onConnect(SocketIOClient client) {
    String userId = client.getHandshakeData().getSingleUrlParam("userId");
//    userId = jwtSupport.getApplicationUser().getId().toString();
//    userId = "8";
    UUID sessionId = client.getSessionId();
    clientCache.saveClient(userId, sessionId, client);
    System.out.println("建立連接");
  }

  /**
   * 客戶端斷開
   *
   * @param client
   */
  @OnDisconnect
  public void onDisconnect(SocketIOClient client) {
    String userId = client.getHandshakeData().getSingleUrlParam("userId");
    if (StringUtils.isNotBlank(userId)) {
      clientCache.deleteSessionClient(userId, client.getSessionId());
      System.out.println("關(guān)閉連接");
    }
  }

  //消息接收入口,當(dāng)接收到消息后,查找發(fā)送目標(biāo)客戶端,并且向該客戶端發(fā)送消息,且給自己發(fā)送消息
  // 暫未使用
  @OnEvent("messageevent")
  public void onEvent(SocketIOClient client, AckRequest request) {
  }
}

本地緩存信息

import com.corundumstudio.socketio.SocketIOClient;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * kcm
 */
@Component
public class ClientCache {

  //本地緩存
  private static Map<String, HashMap<UUID, SocketIOClient>> concurrentHashMap=new ConcurrentHashMap<>();
  /**
   * 存入本地緩存
   * @param userId 用戶ID
   * @param sessionId 頁(yè)面sessionID
   * @param socketIOClient 頁(yè)面對(duì)應(yīng)的通道連接信息
   */
  public void saveClient(String userId, UUID sessionId,SocketIOClient socketIOClient){
    if(StringUtils.isNotBlank(userId)){
      HashMap<UUID, SocketIOClient> sessionIdClientCache=concurrentHashMap.get(userId);
      if(sessionIdClientCache==null){
        sessionIdClientCache = new HashMap<>();
      }
      sessionIdClientCache.put(sessionId,socketIOClient);
      concurrentHashMap.put(userId,sessionIdClientCache);
    }
  }
  /**
   * 根據(jù)用戶ID獲取所有通道信息
   * @param userId
   * @return
   */
  public HashMap<UUID, SocketIOClient> getUserClient(String userId){
    return concurrentHashMap.get(userId);
  }
  /**
   * 根據(jù)用戶ID及頁(yè)面sessionID刪除頁(yè)面鏈接信息
   * @param userId
   * @param sessionId
   */
  public void deleteSessionClient(String userId,UUID sessionId){
    concurrentHashMap.get(userId).remove(sessionId);
  }
}

下面是存儲(chǔ)客戶端連接信息

import com.corundumstudio.socketio.SocketIOClient;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * kcm
 */
@Component
public class ClientCache {

  //本地緩存
  private static Map<String, HashMap<UUID, SocketIOClient>> concurrentHashMap=new ConcurrentHashMap<>();
  /**
   * 存入本地緩存
   * @param userId 用戶ID
   * @param sessionId 頁(yè)面sessionID
   * @param socketIOClient 頁(yè)面對(duì)應(yīng)的通道連接信息
   */
  public void saveClient(String userId, UUID sessionId,SocketIOClient socketIOClient){
    if(StringUtils.isNotBlank(userId)){
      HashMap<UUID, SocketIOClient> sessionIdClientCache=concurrentHashMap.get(userId);
      if(sessionIdClientCache==null){
        sessionIdClientCache = new HashMap<>();
      }
      sessionIdClientCache.put(sessionId,socketIOClient);
      concurrentHashMap.put(userId,sessionIdClientCache);
    }
  }
  /**
   * 根據(jù)用戶ID獲取所有通道信息
   * @param userId
   * @return
   */
  public HashMap<UUID, SocketIOClient> getUserClient(String userId){
    return concurrentHashMap.get(userId);
  }
  /**
   * 根據(jù)用戶ID及頁(yè)面sessionID刪除頁(yè)面鏈接信息
   * @param userId
   * @param sessionId
   */
  public void deleteSessionClient(String userId,UUID sessionId){
    concurrentHashMap.get(userId).remove(sessionId);
  }
}

控制層推送方法

@RestController
@RequestMapping("/push")
public class PushController {
  @Resource
  private ClientCache clientCache;

  @Autowired
  private JwtSupport jwtSupport;

  @GetMapping("/message")
  public String pushTuUser(@Param("id") String id){
    Integer userId = jwtSupport.getApplicationUser().getId();
    HashMap<UUID, SocketIOClient> userClient = clientCache.getUserClient(String.valueOf(userId));
    userClient.forEach((uuid, socketIOClient) -> {
      //向客戶端推送消息
      socketIOClient.sendEvent("chatevent","服務(wù)端推送消息");
    });
    return "success";
  }
}

到此這篇關(guān)于SpringBoot+netty-socketio實(shí)現(xiàn)服務(wù)器端消息推送的文章就介紹到這了,更多相關(guān)SpringBoot netty-socketio服務(wù)器端推送內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java轉(zhuǎn)換流(InputStreamReader/OutputStreamWriter)的使用

    Java轉(zhuǎn)換流(InputStreamReader/OutputStreamWriter)的使用

    本文主要介紹了Java轉(zhuǎn)換流(InputStreamReader/OutputStreamWriter)的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • springboot中server.ssl.key-store配置路徑的問題小結(jié)

    springboot中server.ssl.key-store配置路徑的問題小結(jié)

    這篇文章主要介紹了springboot中server.ssl.key-store配置路徑的問題,文中還記錄了Spring Boot SSL(https)實(shí)例,介紹在web程序中使用自簽名的SSL(HTTPS)證書及創(chuàng)建SSL認(rèn)證,感興趣的朋友跟隨小編一起看看吧
    2024-02-02
  • Java三個(gè)類加載器及它們的相互關(guān)系

    Java三個(gè)類加載器及它們的相互關(guān)系

    Java在需要使用類別的時(shí)候,才會(huì)將類別加載,Java的類別載入是由類別載入器(Class loader)來(lái)達(dá)到的,預(yù)設(shè)上,在程序啟動(dòng)之后,主要會(huì)有三個(gè)類別加載器,文中詳細(xì)介紹了這三個(gè)類加載器,需要的朋友可以參考下
    2021-06-06
  • Jdbc連接數(shù)據(jù)庫(kù)基本步驟詳解

    Jdbc連接數(shù)據(jù)庫(kù)基本步驟詳解

    這篇文章主要為大家詳細(xì)介紹了Jdbc連接數(shù)據(jù)庫(kù)的基本步驟,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • java中如何實(shí)現(xiàn) zip rar 7z 壓縮包解壓

    java中如何實(shí)現(xiàn) zip rar 7z 壓縮包解壓

    這篇文章主要介紹了java中如何實(shí)現(xiàn) zip rar 7z 壓縮包解壓?jiǎn)栴},具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • rabbitmq中routingkey的作用說(shuō)明

    rabbitmq中routingkey的作用說(shuō)明

    這篇文章主要介紹了rabbitmq中routingkey的作用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • springboot整合redis實(shí)現(xiàn)發(fā)送郵箱并驗(yàn)證

    springboot整合redis實(shí)現(xiàn)發(fā)送郵箱并驗(yàn)證

    大家好,本篇文章主要講的是springboot整合redis實(shí)現(xiàn)發(fā)送郵箱并驗(yàn)證,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-01-01
  • java 單播、廣播、組播詳解及實(shí)例代碼

    java 單播、廣播、組播詳解及實(shí)例代碼

    這篇文章主要介紹了java 單播、廣播、組播詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • SpringCloud?Gateway實(shí)現(xiàn)API接口加解密

    SpringCloud?Gateway實(shí)現(xiàn)API接口加解密

    這篇文章主要為大家介紹了SpringCloud?Gateway如何實(shí)現(xiàn)API接口加解密的,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)有一定的幫助,需要的可以參考一下
    2022-06-06
  • Java實(shí)現(xiàn)中文算數(shù)驗(yàn)證碼的實(shí)現(xiàn)示例(算數(shù)運(yùn)算+-*/)

    Java實(shí)現(xiàn)中文算數(shù)驗(yàn)證碼的實(shí)現(xiàn)示例(算數(shù)運(yùn)算+-*/)

    這篇文章主要介紹了Java實(shí)現(xiàn)中文算數(shù)驗(yàn)證碼的實(shí)現(xiàn)示例(算數(shù)運(yùn)算+-*/),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評(píng)論

饶河县| 康平县| 田林县| 铁岭县| 新郑市| 灵丘县| 灯塔市| 河间市| 宕昌县| 沙湾县| 会东县| 永城市| 通州市| 鄂托克前旗| 钟山县| 万盛区| 紫阳县| 龙陵县| 云阳县| 商水县| 永川市| 广昌县| 定边县| 敦化市| 全椒县| 邹城市| 三门峡市| 始兴县| 右玉县| 和田县| 疏附县| 苍梧县| 章丘市| 曲松县| 威海市| 阜南县| 施秉县| 宁安市| 金溪县| 莲花县| 措美县|