文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-04-02 19:55

关注

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

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

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

maven依赖


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

 下面就是代码了

首先是配置参数


#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;


@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;

  
  @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("建立连接");
  }

  
  @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;


@Component
public class ClientCache {

  //本地缓存
  private static Map<String, HashMap<UUID, SocketIOClient>> concurrentHashMap=new ConcurrentHashMap<>();
  
  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);
    }
  }
  
  public HashMap<UUID, SocketIOClient> getUserClient(String userId){
    return concurrentHashMap.get(userId);
  }
  
  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;


@Component
public class ClientCache {

  //本地缓存
  private static Map<String, HashMap<UUID, SocketIOClient>> concurrentHashMap=new ConcurrentHashMap<>();
  
  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);
    }
  }
  
  public HashMap<UUID, SocketIOClient> getUserClient(String userId){
    return concurrentHashMap.get(userId);
  }
  
  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","服务端推送消息");
    });
    return "success";
  }
}

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

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-服务器
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯