• 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实现实时推送的更多相关文章

  1. springboot搭建一个简单的websocket的实时推送应用

    说一下实用springboot搭建一个简单的websocket 的实时推送应用 websocket是什么 WebSocket是一种在单个TCP连接上进行全双工通信的协议 我们以前用的http协议只能单 ...

  2. 使用SignalR ASP.NET Core来简单实现一个后台实时推送数据给Echarts展示图表的功能

    什么是 SignalR ASP.NET Core ASP.NET Core SignalR 是一种开放源代码库,可简化将实时 web 功能添加到应用程序的功能. 实时 web 功能使服务器端代码可以立 ...

  3. 【原创】node+express+socket搭建一个实时推送应用

    技术背景 Web领域的实时推送技术,也被称作Realtime技术.这种技术要达到的目的是让用户不需要刷新浏览器就可以获得实时更新. 应用场景: 监控系统:后台硬件热插拔.LED.温度.电压发生变化 即 ...

  4. SignalR实时推送

    SignalR 的实现机制与 .NET WCF 或 Remoting 是相似的,都是使用远程代理来实现.在具体使用上,有两种不同目的的接口:PersistentConnection 和 Hubs,其中 ...

  5. HTML5 WebSocket 实时推送信息测试demo

    测试一下HTML5的websocket功能,实现了客户端→服务器实时推送信息到客户端,包括推送图片: websocket实现MessageInbound类 onTextMessage()/onBina ...

  6. 基于Node.js的实时推送 juggernaut

    基于Node.js的实时推送 juggernaut Juggernaut 基于 Node.js 构建.为浏览器和服务器端提供一个实时的连接,可在客户端和服务器端进行数据的实时推送,适合多角色游戏.聊天 ...

  7. 关于 实时推送技术--WebSocket的 知识分享

    今天学习了关于WebSocket的知识,觉得挺有用的,在这记录一下,也和大家分享一下!!有兴趣的可以看看哦 WebSocket简介 Web领域的实时推送技术,也被称作Realtime技术.这种技术要达 ...

  8. dwr3+spring实现消息实时推送

    最近项目要实现一个消息推送的功能,主要就是发送站内信或者系统主动推送消息给当前在线的用户.每次的消息内容保存数据库,方便用户下次登录后也能看到.如果当前用户在线,收到站内信就主动弹出提示.一开始想到的 ...

  9. javascript跨域传递消息 / 服务器实时推送总结

    参考文档,下面有转载[非常好的两篇文章]: http://www.cnblogs.com/loveis715/p/4592246.html [跨源的各种方法总结] http://kb.cnblogs. ...

随机推荐

  1. git 查看日志记录

    1.git log 如果日志特别多的话,在git bash中,按向下键来查看更多,按q键退出查看日志. 2.git show 查看最近一次commit内容,也可以后面加commit号,单独查看此次版本 ...

  2. Go中使用seed得到相同随机数的问题

    1. 重复的随机数 废话不多说,首先我们来看使用seed的一个很神奇的现象. func main() { for i := 0; i < 5; i++ { rand.Seed(time.Now( ...

  3. BootstrapVue 安装指南

    BootstrapVue 是基于 Bootstrap v4 + Vue.js 的前端 UI 框架.BootstrapVue 作为学习 Vue.js 框架本身的入门框架,我认为是非常不错的.Bootst ...

  4. QQ第三方授权登录OAuth2.0实现(Java)

    准备材料 1.已经备案好的域名 2.服务器(域名和服务器为统一主体或域名已接入服务器) 3.QQ号 4.开发流程:https://wiki.connect.qq.com/%E5%87%86%E5%A4 ...

  5. 执行Django数据迁移,报错 1091

    问题描述 今天在Pycharm 中的Terminal下,执行数据迁移操作时,第一步: Python manage.py makemigrations ,是没有任何问题,但就是在执行真正的数据迁移时,也 ...

  6. Rust入坑指南:坑主驾到

    欢迎大家和我一起入坑Rust,以后我就是坑主,我主要负责在前面挖坑,各位可以在上面看,有手痒的也可以和我一起挖.这个坑到底有多深?我也不知道,我是抱着有多深就挖多深的心态来的,下面我先跳了,各位请随意 ...

  7. docker升级后启动报错400 Client Error: Bad Request ("Unknown runtime specified docker-runc")

    宝塔面板docker升级后启动容器时报错400 Client Error: Bad Request ("Unknown runtime specified docker-runc" ...

  8. ASRWGAN: Wasserstein Generative Adversarial Network for Audio Super Resolution

    ASEGAN:WGAN音频超分辨率 这篇文章并不具有权威性,因为没有发表,说不定是外国的某个大学的毕业设计,或者课程结束后的作业.或者实验报告. CS230: Deep Learning, Sprin ...

  9. python编程基础之十六

    for in 循环,与其说是循环不如说精确点交遍历 for 变量名 in + 迭代对象 语句A else: 语句B 作用:一次访问迭代对象中的元素并赋值给变量 循环终止时,执行else语句块,如果br ...

  10. GO 第一个程序Hello world

    第一个程序:HelloWorld 一.go项目工程结构 配置好工作目录后,就可以编码开发了,在这之前,我们看下go的通用项目结构,这里的结构主要是源代码相应地资源文件存放目录结构. 1.1 gopat ...