一、前言

websocketsocket.io区别?
websocket
  1. 一种让客户端和服务器之间能进行双向实时通信的技术
  2. 使用时,虽然主流浏览器都已经支持,但仍然可能有不兼容的情况
  3. 适合用于client和基于node搭建的服务端使用
socket.io
  1. 将WebSocket、AJAX和其它的通信方式全部封装成了统一的通信接口
  2. 使用时,不用担心兼容问题,底层会自动选用最佳的通信方式
  3. 适合进行服务端和客户端双向数据通信

w3cschool上对socket.io的描述如下:

本文将实现
  1. 基于springboot2.1.8.RELEASE集成netty-socketio : 仿node.js实现的socket.io服务端
  2. 集成socket.io-clientsocket.io客户端
  3. 实现服务端客户端之间的通信

二、Java集成socket.io服务端

1、pom.xml中引入所需依赖

温馨小提示:这里为了方便将后面需要的客户端socket.io-client依赖一起直接引入了哦~

<!-- netty-socketio: 仿`node.js`实现的socket.io服务端 -->
<dependency><groupId>com.corundumstudio.socketio</groupId><artifactId>netty-socketio</artifactId><version>1.7.7</version>
</dependency>
<!-- socket.io客户端 -->
<dependency><groupId>io.socket</groupId><artifactId>socket.io-client</artifactId><version>1.0.0</version>
</dependency>

2、application.yml中配置socket.io服务端

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

3、socket.io服务端配置类

@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;@Beanpublic 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);}}

4、socket.io服务端服务层

服务类

public interface ISocketIOService {/*** 启动服务*/void start();/*** 停止服务*/void stop();/*** 推送信息给指定客户端** @param userId:     客户端唯一标识* @param msgContent: 消息内容*/void pushMessageToUser(String userId, String msgContent);
}

服务实现类:

@Slf4j
@Service(value = "socketIOService")
public class SocketIOServiceImpl implements ISocketIOService {/*** 存放已连接的客户端*/private static Map<String, SocketIOClient> clientMap = new ConcurrentHashMap<>();/*** 自定义事件`push_data_event`,用于服务端与客户端通信*/private static final String PUSH_DATA_EVENT = "push_data_event";@Autowiredprivate SocketIOServer socketIOServer;/*** Spring IoC容器创建之后,在加载SocketIOServiceImpl Bean之后启动*/@PostConstructprivate void autoStartup() {start();}/*** Spring IoC容器在销毁SocketIOServiceImpl Bean之前关闭,避免重启项目服务端口占用问题*/@PreDestroyprivate void autoStop() {stop();}@Overridepublic void start() {// 监听客户端连接socketIOServer.addConnectListener(client -> {log.debug("************ 客户端: " + getIpByClient(client) + " 已连接 ************");// 自定义事件`connected` -> 与客户端通信  (也可以使用内置事件,如:Socket.EVENT_CONNECT)client.sendEvent("connected", "你成功连接上了哦...");String userId = getParamsByClient(client);if (userId != null) {clientMap.put(userId, client);}});// 监听客户端断开连接socketIOServer.addDisconnectListener(client -> {String clientIp = getIpByClient(client);log.debug(clientIp + " *********************** " + "客户端已断开连接");String userId = getParamsByClient(client);if (userId != null) {clientMap.remove(userId);client.disconnect();}});// 自定义事件`client_info_event` -> 监听客户端消息socketIOServer.addEventListener(PUSH_DATA_EVENT, String.class, (client, data, ackSender) -> {// 客户端推送`client_info_event`事件时,onData接受数据,这里是string类型的json数据,还可以为Byte[],object其他类型String clientIp = getIpByClient(client);log.debug(clientIp + " ************ 客户端:" + data);});// 启动服务socketIOServer.start();// broadcast: 默认是向所有的socket连接进行广播,但是不包括发送者自身,如果自己也打算接收消息的话,需要给自己单独发送。new Thread(() -> {int i = 0;while (true) {try {// 每3秒发送一次广播消息Thread.sleep(3000);socketIOServer.getBroadcastOperations().sendEvent("myBroadcast", "广播消息 " + DateUtil.now());} catch (InterruptedException e) {e.printStackTrace();}}}).start();}@Overridepublic void stop() {if (socketIOServer != null) {socketIOServer.stop();socketIOServer = null;}}@Overridepublic void pushMessageToUser(String userId, String msgContent) {SocketIOClient client = clientMap.get(userId);if (client != null) {client.sendEvent(PUSH_DATA_EVENT, msgContent);}}/*** 获取客户端url中的userId参数(这里根据个人需求和客户端对应修改即可)** @param client: 客户端* @return: java.lang.String*/private String getParamsByClient(SocketIOClient client) {// 获取客户端url参数(这里的userId是唯一标识)Map<String, List<String>> params = client.getHandshakeData().getUrlParams();List<String> userIdList = params.get("userId");if (!CollectionUtils.isEmpty(userIdList)) {return userIdList.get(0);}return null;}/*** 获取连接的客户端ip地址** @param client: 客户端* @return: java.lang.String*/private String getIpByClient(SocketIOClient client) {String sa = client.getRemoteAddress().toString();String clientIp = sa.substring(1, sa.indexOf(":"));return clientIp;}}

三、Java开发socket.io客户端

  1. socket.emit:发送数据到服务端事件
  2. socket.on: 监听服务端事件
@Slf4j
public class SocketIOClientLaunch {public static void main(String[] args) {// 服务端socket.io连接通信地址String url = "http://127.0.0.1:8888";try {IO.Options options = new IO.Options();options.transports = new String[]{"websocket"};options.reconnectionAttempts = 2;// 失败重连的时间间隔options.reconnectionDelay = 1000;// 连接超时时间(ms)options.timeout = 500;// userId: 唯一标识 传给服务端存储final Socket socket = IO.socket(url + "?userId=1", options);socket.on(Socket.EVENT_CONNECT, args1 -> socket.send("hello..."));// 自定义事件`connected` -> 接收服务端成功连接消息socket.on("connected", objects -> log.debug("服务端:" + objects[0].toString()));// 自定义事件`push_data_event` -> 接收服务端消息socket.on("push_data_event", objects -> log.debug("服务端:" + objects[0].toString()));// 自定义事件`myBroadcast` -> 接收服务端广播消息socket.on("myBroadcast", objects -> log.debug("服务端:" + objects[0].toString()));socket.connect();while (true) {Thread.sleep(3000);// 自定义事件`push_data_event` -> 向服务端发送消息socket.emit("push_data_event", "发送数据 " + DateUtil.now());}} catch (Exception e) {e.printStackTrace();}}}

四、运行测试

当客户端上线后,会通过自定义事件push_data_event每隔3秒向服务端发送消息,日志如下

而服务端中跑了一个广播消息(自定义事件myBroadcast) 每隔3秒也会返回给客户端

广播事件: 向所有的socket连接进行广播发送消息数据

socketIOServer.getBroadcastOperations().sendEvent("myBroadcast", "广播消息 " + DateUtil.now());

日志如下:

编写服务端主动发送消息给客户端接口

@RestController
@RequestMapping("/api/socket.io")
@Api(tags = "SocketIO测试-接口")
public class SocketIOController {@Autowiredprivate ISocketIOService socketIOService;@PostMapping(value = "/pushMessageToUser", produces = Constants.CONTENT_TYPE)@ApiOperation(value = "推送信息给指定客户端", httpMethod = "POST", response = ApiResult.class)public ApiResult pushMessageToUser(@RequestParam String userId, @RequestParam String msgContent) {socketIOService.pushMessageToUser(userId, msgContent);return ApiResult.ok();}}

调用接口测试发送helloworld…

五、总结

socket.io通信,服务端:

1.socketIOServer.addConnectListener:监听客户端连接
2. socketIOServer.addDisconnectListener:监听客户端断开连接
3. socketIOServer.addEventListener:监听客户端传输的消息
4. client.sendEvent("自定义事件名称", "消息内容"):服务端向指定的clien客户端发送消息
5. socketIOServer.getBroadcastOperations().sendEvent("自定义事件名称", "消息内容"):服务端发送广播消息给所有客户端

socket.io通信,客户端:
  1. IO.socket(url):与指定的socket.io服务端建立连接
  2. socket.emit:发送数据到服务端事件
  3. socket.on: 监听服务端事件

本文案例demo源码

https://gitee.com/zhengqingya/java-workspace

SpringBoot(23) 集成socket.io服务端和客户端实现通信相关推荐

  1. socket.io服务端是java_SpringBoot(23) 集成socket.io服务端和客户端实现通信

    @Slf4j @Service(value = "socketIOService") public class SocketIOServiceImpl implements ISo ...

  2. 2-3 建立简易TCP服务端、客户端【socket server/client】【socket、bind、listen、accept、send、closesocket】【conect、recv】

    2-3 建立简易TCP服务端.客户端 文章目录 2-3 建立简易TCP服务端.客户端 0-前言 1-服务端简易功能 2-客户端简易功能 3-代码逻辑 4-服务端 4-1 建立socket 4-2 绑定 ...

  3. Java中利用socket实现简单的服务端与客户端的通信(中级)——实现任意双向通信

    本文计划采用socket实现客户端和服务端的任意双向通信,即客户端可以随时给服务端发消息,服务端也可以随时给客户端发消息,最终结果就是一个类似与QQ的聊天软件的功能. 以下代码可以直接拷贝到Eclip ...

  4. Java中利用socket实现简单的服务端与客户端的通信(基础级)

    在上一篇文章中,简单的介绍了java中入门级的socket编程,简单的实现了客户端像服务器端发送数据,服务器端将数据接收并显示在控制台,没有涉及多线程.上一篇文章的链接:Java中利用socket实现 ...

  5. Java中利用socket实现简单的服务端与客户端的通信(入门级)

    Java编程中,要想要使用网络通信,就离不开Socket编程,在此对socket进行简单的介绍.首先声明,这是一个入门级的介绍,仅仅简单的实现了客户端向服务端发送数据,服务端正常的接收数据,当接收到特 ...

  6. SpringBoot使用Mina框架进行服务端与客户端数据通信

    pom.xml引入 <dependency><groupId>org.apache.mina</groupId><artifactId>mina-cor ...

  7. java 集成 cas系统 服务端和客户端配置

    http://blog.csdn.net/yunye114105/article/details/7997041 参考: http://blog.csdn.net/diyagea/article/de ...

  8. Java实现服务端和客户端的通信(文件下载)

    网络编程 网络通信的介绍 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据 两台电脑连在一起就组成了一个计算机网络.我们通过光纤连接到电信的网关,中国电信通过海底光缆和美国电信网关连接,你 ...

  9. 使用WebSocket实现服务端和客户端的通信

    开发中经常会有这样的使用场景.如某个用户在一个数据上做了xx操作, 与该数据相关的用户在线上的话,需要实时接收到一条信息. 这种可以使用WebSocket来实现. 另外,对于消息,可以定义一个类进行固 ...

最新文章

  1. 如何制作风格迁移图?
  2. ASP.NET Razor – C# 变量简介
  3. Nodejs介绍及其安装
  4. VTK:可视化算法之PineRootDecimation
  5. html5时间画布走动,javascript+HTML5 canvas绘制时钟功能示例
  6. python 对axis的理解
  7. 【MSDN文摘】使用自定义验证组件库扩展 Windows 窗体: Form Scope
  8. shell如何解决mysql交互式_shell脚本与mysql交互方法汇总
  9. CentOS 安装MySQL(rpm)提示错误Header V3 DSA/SHA1 Signature
  10. Android仿华为天气绘制刻度盘
  11. 2015年10月26日作业
  12. 手机不能访问html文件,手机如何解决禁止访问网页
  13. 数据挖掘经典算法--priori算法
  14. 智能型电话远程遥控器
  15. 腾讯云主机配置tomcat服务器
  16. dumb-init:一个Docker容器初始化系统
  17. python控制小爱同学_神秘鸭,用Siri小爱同学语音助手控制你的电脑
  18. 从实战经验来看 究竟如何才能做出赚钱的量化投资策略?
  19. 项目管理必备工具——甘特图
  20. ActiveX控件之制作图片属性页

热门文章

  1. 我国SM9密钥交换协议正式成为ISO/IEO国际标准,SM9算法全系完成国际标准认证
  2. vue中使用moment处理时间戳转换成日期或时间格式
  3. 2019年公务员计算机(大类)类,2019年国家公务员考试证监会参公事业单位计算机类大纲...
  4. js之深浅克隆(深浅拷贝)
  5. 关闭shift中英文切换 英文代码/中文注释随意切换着写。
  6. 用CocosCreator来做一个黄金矿工吧(二)
  7. 双目立体匹配:AD Census
  8. Revit(8)-数据结构-类别、族概念
  9. 利用Stram来递归生成树形结构
  10. centos下一键安装lamp环境,快捷,方便