热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

SpringBoot+netty-socketio实现服务器端消息推送

这篇文章主要介绍了SpringBoot+netty-socketio实现服务器端消息推送,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

首先:因为工作需要,需要对接socket.io框架对接,所以目前只能使用netty-socketio。websocket是不支持对接socket.io框架的。

netty-socketio顾名思义他是一个底层基于netty'实现的socket。

在springboot项目中的集成,请看下面的代码

maven依赖


 com.corundumstudio.socketio
 netty-socketio
 1.7.11

 下面就是代码了

首先是配置参数

#socketio配置
socketio:
 host: localhost
 port: 9099
 # 设置最大每帧处理数据的长度,防止他人利用大数据来攻击服务器
 maxFramePayloadLength: 1048576
 # 设置http交互最大内容长度
 maxHttpContentLength: 1048576
 # socket连接数大小(如只监听一个端口boss线程组为1即可)
 bossCount: 1
 workCount: 100
 allowCustomRequests: true
 # 协议升级超时时间(毫秒),默认10秒。HTTP握手升级为ws协议超时时间
 upgradeTimeout: 1000000
 # Ping消息超时时间(毫秒),默认60秒,这个时间间隔内没有接收到心跳消息就会发送超时事件
 pingTimeout: 6000000
 # Ping消息间隔(毫秒),默认25秒。客户端向服务器发送一条心跳消息间隔
 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("启动正常");
  }
}

在就是监听代码

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("关闭连接");
    }
  }

  //消息接收入口,当接收到消息后,查找发送目标客户端,并且向该客户端发送消息,且给自己发送消息
  // 暂未使用
  @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> cOncurrentHashMap=new ConcurrentHashMap<>();
  /**
   * 存入本地缓存
   * @param userId 用户ID
   * @param sessionId 页面sessionID
   * @param socketIOClient 页面对应的通道连接信息
   */
  public void saveClient(String userId, UUID sessionId,SocketIOClient socketIOClient){
    if(StringUtils.isNotBlank(userId)){
      HashMap sessiOnIdClientCache=concurrentHashMap.get(userId);
      if(sessiOnIdClientCache==null){
        sessiOnIdClientCache= new HashMap<>();
      }
      sessionIdClientCache.put(sessionId,socketIOClient);
      concurrentHashMap.put(userId,sessionIdClientCache);
    }
  }
  /**
   * 根据用户ID获取所有通道信息
   * @param userId
   * @return
   */
  public HashMap getUserClient(String userId){
    return concurrentHashMap.get(userId);
  }
  /**
   * 根据用户ID及页面sessionID删除页面链接信息
   * @param userId
   * @param sessionId
   */
  public void deleteSessionClient(String userId,UUID sessionId){
    concurrentHashMap.get(userId).remove(sessionId);
  }
}

下面是存储客户端连接信息

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> cOncurrentHashMap=new ConcurrentHashMap<>();
  /**
   * 存入本地缓存
   * @param userId 用户ID
   * @param sessionId 页面sessionID
   * @param socketIOClient 页面对应的通道连接信息
   */
  public void saveClient(String userId, UUID sessionId,SocketIOClient socketIOClient){
    if(StringUtils.isNotBlank(userId)){
      HashMap sessiOnIdClientCache=concurrentHashMap.get(userId);
      if(sessiOnIdClientCache==null){
        sessiOnIdClientCache= new HashMap<>();
      }
      sessionIdClientCache.put(sessionId,socketIOClient);
      concurrentHashMap.put(userId,sessionIdClientCache);
    }
  }
  /**
   * 根据用户ID获取所有通道信息
   * @param userId
   * @return
   */
  public HashMap getUserClient(String userId){
    return concurrentHashMap.get(userId);
  }
  /**
   * 根据用户ID及页面sessionID删除页面链接信息
   * @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 userClient = clientCache.getUserClient(String.valueOf(userId));
    userClient.forEach((uuid, socketIOClient) -> {
      //向客户端推送消息
      socketIOClient.sendEvent("chatevent","服务端推送消息");
    });
    return "success";
  }
}

到此这篇关于SpringBoot+netty-socketio实现服务器端消息推送的文章就介绍到这了,更多相关SpringBoot netty-socketio服务器端推送内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!


推荐阅读
  • 前言微服务架构(MicroserviceArchitecture)是一种架构概念,旨在通过将功能分解到各个离散的服务中以实现对解决方案的解耦。你可以将其看作是在架构层次而非获取服务 ... [详细]
  • 开发笔记:深度探索!Android之OkHttp网络架构源码解析
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了深度探索!Android之OkHttp网络架构源码解析相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 利用ipv6技术,废旧笔记本变成server
    如果你家的路由器已经get到了ipv6地址,并且你家的电脑也获取了有效的ipv6地址,在广域网的设备可以访问到。那恭喜你,再配合我这个dd ... [详细]
  • 13Linux基本命令和配置服务器来电后自动开机
    本节所讲内容:Linux终端介绍Shell提示符BashShell基本语法基本命令的使用:ls、pwd、cd查看系统和BIOS硬件时间Linux如何获得 ... [详细]
  • 这篇文章主要讲解了“GradeBook类怎么定义”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Grad ... [详细]
  • 2019 年 Firebase 峰会上发布的新功能
    作者FrancisMa,HeadofProductFirebase的使命是帮助移动开发者和Web开发者迈向成功,但考虑到Firebase每个月有超过200万个活跃的应 ... [详细]
  • socket8 [命名管道]
    ::命名管道不但能实现同一台机器上两个进程通信,还能在网络中不同机器上的两个进程之间的通信机制。与邮槽不同,命名管道是采用基于连接并且可靠的传输方式,所以命名管道传输数据只能一对一 ... [详细]
  • docker整体了解
    Docker是一个基于LXC技术构建的容器引擎,基于Go语言开发,遵循Apache2.0协议开源Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移 ... [详细]
  • python有什么应用领域[python常见问题]
    python语言可以用来开发游戏,用于大数据的挖掘和处理,开发web,应用在系统运维,云计算,金融理财分析,人工智能等涉及 ... [详细]
  • php开发属于哪个类别(php类和对象的区别)
    导读:本篇文章编程笔记来给大家介绍有关php开发属于哪个类别的相关内容,希望对大家有所帮助,一起来看看吧。本文目录一览:1、php属于什 ... [详细]
  • gzip html php,Apache启用Gzip压缩的方法,压缩css、js、html等文件
    1、开启模块并添加配置项目a、linux服务器vietchttpdconfhttpd.conf本地服务器找到apacheconf文件夹下面httpd.confb、查找LoadMod ... [详细]
  • 我的LINUX学习之路之二十一之web服务器简单搭建
    今天说说如何搭建HTTP服务器!目的:使用“多IP地址”方法实现多个网站。使用“主机头名”方法实现多个网站。使用“多端口”方法实现多个网站。这回用图形界 ... [详细]
  • 创建新的用户并配置jdk,tomcat环境
    进入root账号添加用户输入useraddqwe设置密码输入passwdqwe重复两遍输入密码,设置完成后切换用户输入su-qwe进入其他服务器复制jdk文 ... [详细]
  • Nginx简介Nginx(enginex)是一个高性能的HTTP和反向代理服务器,也是一个IMAPPOP3SMTP代理服务器。Nginx是由IgorSysoev为 ... [详细]
  • 面试:Websocket简介WebSocket是一种与HTTP不同的协议。两者都位于OSI模型的应用层,并且都依赖于传输层的TCP协议。虽然它们不同& ... [详细]
author-avatar
W14154988
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有