SpringBoot项目集成socketIo实现实时推送

- netty-socketio maven依赖
<dependency>
<groupId>com.corundumstudio.socketio</groupId>
<artifactId>netty-socketio</artifactId>
<version>1.7.7</version>
</dependency>
- application.properties相关配置
#============================================================================
# netty socket io setting
#============================================================================
# host在本地测试可以设置为localhost或者本机IP,在Linux服务器跑可换成服务器IP
socketio.host=localhost
socketio.port=9099
# 设置最大每帧处理数据的长度,防止他人利用大数据来攻击服务器
socketio.maxFramePayloadLength=1048576
# 设置http交互最大内容长度
socketio.maxHttpContentLength=1048576
# socket连接数大小(如只监听一个端口boss线程组为1即可)
socketio.bossCount=1
socketio.workCount=100
socketio.allowCustomRequests=true
# 协议升级超时时间(毫秒),默认10秒。HTTP握手升级为ws协议超时时间
socketio.upgradeTimeout=1000000
# Ping消息超时时间(毫秒),默认60秒,这个时间间隔内没有接收到心跳消息就会发送超时事件
socketio.pingTimeout=6000000
# Ping消息间隔(毫秒),默认25秒。客户端向服务器发送一条心跳消息间隔
socketio.pingInterval=25000
- SocketIOConfig.java配置文件相关配置
package com.vcgeek.hephaestus.socketio; import com.corundumstudio.socketio.SocketConfig;
import com.corundumstudio.socketio.SocketIOServer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; /**
* 功能描述
*
* @author: zyu
* @description:
* @date: 2019/4/23 10:40
*/
@Configuration
public class SocketIOConfig { @Value("${socketio.host}")
private String host; @Value("${socketio.port}")
private Integer port; @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; /**
* 以下配置在上面的application.properties中已经注明
* @return
*/
@Bean
public SocketIOServer socketIOServer() {
SocketConfig socketConfig = new SocketConfig();
socketConfig.setTcpNoDelay(true);
socketConfig.setSoLinger(0);
com.corundumstudio.socketio.Configuration config = new com.corundumstudio.socketio.Configuration();
config.setSocketConfig(socketConfig);
config.setHostname(host);
config.setPort(port);
config.setBossThreads(bossCount);
config.setWorkerThreads(workCount);
config.setAllowCustomRequests(allowCustomRequests);
config.setUpgradeTimeout(upgradeTimeout);
config.setPingTimeout(pingTimeout);
config.setPingInterval(pingInterval);
return new SocketIOServer(config);
} }
以下就是提供一个SocketIOService接口,供其他地方需要使用时调用。
package com.vcgeek.hephaestus.socketio; import com.vcgeek.hephaestus.pojo.PushMessage; /**
* 功能描述
*
* @author: zyu
* @description:
* @date: 2019/4/23 10:41
*/
public interface SocketIOService { //推送的事件
public static final String PUSH_EVENT = "push_event"; // 启动服务
void start() throws Exception; // 停止服务
void stop(); // 推送信息
void pushMessageToUser(PushMessage pushMessage); }
- SocketIOServiceImpl.java接口实现类
package com.vcgeek.hephaestus.socketio; import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.vcgeek.hephaestus.pojo.PushMessage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; /**
* 功能描述
*
* @author: zyu
* @description:
* @date: 2019/4/23 10:42
*/
@Service(value = "socketIOService")
public class SocketIOServiceImpl implements SocketIOService { // 用来存已连接的客户端
private static Map<String, SocketIOClient> clientMap = new ConcurrentHashMap<>(); @Autowired
private SocketIOServer socketIOServer; /**
* Spring IoC容器创建之后,在加载SocketIOServiceImpl Bean之后启动
*
* @throws Exception
*/
@PostConstruct
private void autoStartup() throws Exception {
start();
} /**
* Spring IoC容器在销毁SocketIOServiceImpl Bean之前关闭,避免重启项目服务端口占用问题
*
* @throws Exception
*/
@PreDestroy
private void autoStop() throws Exception {
stop();
} @Override
public void start() throws Exception {
// 监听客户端连接
socketIOServer.addConnectListener(client -> {
String loginUserNum = getParamsByClient(client);
if (loginUserNum != null) {
System.out.println(loginUserNum);
System.out.println("SessionId: " + client.getSessionId());
System.out.println("RemoteAddress: " + client.getRemoteAddress());
System.out.println("Transport: " + client.getTransport());
clientMap.put(loginUserNum, client);
}
}); // 监听客户端断开连接
socketIOServer.addDisconnectListener(client -> {
String loginUserNum = getParamsByClient(client);
if (loginUserNum != null) {
clientMap.remove(loginUserNum);
System.out.println("断开连接: " + loginUserNum);
System.out.println("断开连接: " + client.getSessionId());
client.disconnect();
}
}); // 处理自定义的事件,与连接监听类似
socketIOServer.addEventListener("text", Object.class, (client, data, ackSender) -> {
// TODO do something
client.getHandshakeData();
System.out.println( " 客户端:************ " + data); }); socketIOServer.start();
} @Override
public void stop() {
if (socketIOServer != null) {
socketIOServer.stop();
socketIOServer = null;
}
} @Override
public void pushMessageToUser(PushMessage pushMessage) {
String loginUserNum = pushMessage.getLoginUserNum();
if (StringUtils.isNotBlank(loginUserNum)) {
SocketIOClient client = clientMap.get(loginUserNum);
if (client != null)
client.sendEvent(PUSH_EVENT, pushMessage);
}
} /**
* 此方法为获取client连接中的参数,可根据需求更改
* @param client
* @return
*/
private String getParamsByClient(SocketIOClient client) {
// 从请求的连接中拿出参数(这里的loginUserNum必须是唯一标识)
Map<String, List<String>> params = client.getHandshakeData().getUrlParams();
List<String> list = params.get("loginUserNum");
if (list != null && list.size() > 0) {
return list.get(0);
}
return null;
} public static Map<String, SocketIOClient> getClientMap() {
return clientMap;
} public static void setClientMap(Map<String, SocketIOClient> clientMap) {
SocketIOServiceImpl.clientMap = clientMap;
}
}
- 前端相关测试页面编写
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>NETTY SOCKET.IO DEMO</title>
<base>
<script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/socket.io/2.2.0/socket.io.js"></script>
<style>
body {
padding: 20px;
}
#console {
height: 450px;
overflow: auto;
}
.username-msg {
color: orange;
}
.connect-msg {
color: green;
}
.disconnect-msg {
color: red;
}
</style>
</head> <body>
<div id="console" class="well"></div>
<button id="btnSend" onclick="send()">发送数据</button>
</body>
<script type="text/javascript">
var socket;
connect(); function connect() {
var loginUserNum = '79';
var opts = {
query: 'loginUserNum=' + loginUserNum
};
socket = io.connect('http://localhost:9099', opts);
socket.on('connect', function () {
console.log("连接成功");
serverOutput('<span class="connect-msg">连接成功</span>');
});
socket.on('push_event', function (data) {
output('<span class="username-msg">' + data + ' </span>');
console.log(data); }); socket.on('disconnect', function () {
serverOutput('<span class="disconnect-msg">' + '已下线! </span>');
});
} function output(message) {
var element = $("<div>" + " " + message + "</div>");
$('#console').prepend(element);
} function serverOutput(message) {
var element = $("<div>" + message + "</div>");
$('#console').prepend(element);
} function send() {
console.log('发送数据');
socket.emit('text','你好');
} </script>
</html>
文章转载:https://www.jianshu.com/p/c67853e729e2
SpringBoot项目集成socketIo实现实时推送的更多相关文章
- springboot搭建一个简单的websocket的实时推送应用
说一下实用springboot搭建一个简单的websocket 的实时推送应用 websocket是什么 WebSocket是一种在单个TCP连接上进行全双工通信的协议 我们以前用的http协议只能单 ...
- 使用SignalR ASP.NET Core来简单实现一个后台实时推送数据给Echarts展示图表的功能
什么是 SignalR ASP.NET Core ASP.NET Core SignalR 是一种开放源代码库,可简化将实时 web 功能添加到应用程序的功能. 实时 web 功能使服务器端代码可以立 ...
- 【原创】node+express+socket搭建一个实时推送应用
技术背景 Web领域的实时推送技术,也被称作Realtime技术.这种技术要达到的目的是让用户不需要刷新浏览器就可以获得实时更新. 应用场景: 监控系统:后台硬件热插拔.LED.温度.电压发生变化 即 ...
- SignalR实时推送
SignalR 的实现机制与 .NET WCF 或 Remoting 是相似的,都是使用远程代理来实现.在具体使用上,有两种不同目的的接口:PersistentConnection 和 Hubs,其中 ...
- HTML5 WebSocket 实时推送信息测试demo
测试一下HTML5的websocket功能,实现了客户端→服务器实时推送信息到客户端,包括推送图片: websocket实现MessageInbound类 onTextMessage()/onBina ...
- 基于Node.js的实时推送 juggernaut
基于Node.js的实时推送 juggernaut Juggernaut 基于 Node.js 构建.为浏览器和服务器端提供一个实时的连接,可在客户端和服务器端进行数据的实时推送,适合多角色游戏.聊天 ...
- 关于 实时推送技术--WebSocket的 知识分享
今天学习了关于WebSocket的知识,觉得挺有用的,在这记录一下,也和大家分享一下!!有兴趣的可以看看哦 WebSocket简介 Web领域的实时推送技术,也被称作Realtime技术.这种技术要达 ...
- dwr3+spring实现消息实时推送
最近项目要实现一个消息推送的功能,主要就是发送站内信或者系统主动推送消息给当前在线的用户.每次的消息内容保存数据库,方便用户下次登录后也能看到.如果当前用户在线,收到站内信就主动弹出提示.一开始想到的 ...
- javascript跨域传递消息 / 服务器实时推送总结
参考文档,下面有转载[非常好的两篇文章]: http://www.cnblogs.com/loveis715/p/4592246.html [跨源的各种方法总结] http://kb.cnblogs. ...
随机推荐
- java List转换和数组互转
1.List转Array ArrayList<String> list=new ArrayList<String>(); String[] strings = new Stri ...
- Flask基础(02)-->搭建Flask项目虚拟环境
什么是虚拟环境? 虚拟环境:其实就是一个文件夹,是python环境的复制 为什么要搭建虚拟环境? 因为一台计算机上可能要同时开发多个不同的项目,那么这些项目有可能用到同一个包的不同版本,如此一来,我们 ...
- _self.$scopedSlots.default is not a function报错
问题: 当同一页面有elementUI的多个table表格时,如果用到v-if来动态展示表格,切换时出现如下报错: 原因: 是因为表格是element-ui通过循环产生的,而vue在dom重新渲染时有 ...
- 一文读懂Java GC原理和调优
概述 本文介绍GC基础原理和理论,GC调优方法思路和方法,基于Hotspot jdk1.8,学习之后将了解如何对生产系统出现的GC问题进行排查解决 阅读时长约30分钟,内容主要如下: GC基础原理,涉 ...
- Scala Try Catch Finally
Scala Try Catch Finally: 在Java中返回值优先级顺序:finally最高, try,catch 选其一,try中抛异常,返回catch,不抛异常,返回try,. public ...
- Redis开发与运维:数据迁移
问题 最近项目重构,提前想把一台上的redis实例转移到另一台redis实例上. 源redis数据库:阿里云Redis.VPC网络.Server版本2.8.19 目标数据库:阿里云Redis.VPC网 ...
- CSDN VIP如何添加引流自定义栏目
几个月前我也开始在csdn上开了博客,一来给自己加几个少的可怜的流量,再者,让公众号的原创文章获得更多的曝光,让有需要的同学看到. 写过csdn博客的同学都知道,默认只有打赏c币功能:也没有专门广告位 ...
- hash长度扩展攻击
这里面就放一张百度百科的解释吧,emmm 反正我是看不懂还是做一下题来巩固一下吧 CTF中的hash长度攻击 进入网页你会发现页面显示  我这里没有看到什么可以利用的,抓了一下包也没有什么有可以利 ...
- iOS性能优化-预排版
参考地址:https://blog.ibireme.com/2015/11/12/smooth_user_interfaces_for_ios/ 前面一篇说了异步绘制文字,异步渲染图片,这篇主要是预排 ...
- Go语言及Beego框架环境搭建
在开始环境搭建之前,我们先一起来看看: Go有什么优势: 不用虚拟机,它可直接编译成机器码,除了glibc外没有其他外部依赖,部署十分方便,就是扔一个文件就完成了. 天生支持并发,可以充分的利用多核, ...