springboot中netty-socketio的简单使用
客户端:
服务器端:
1.导入依赖
<dependency>
<groupId>com.corundumstudio.socketio</groupId>
<artifactId>netty-socketio</artifactId>
<version>1.7.7</version>
</dependency>
2.配置类
package com.example.demo2;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.SpringAnnotationScanner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class NettySocketioConfig {
/**
* netty-socketio服务器
*/
@Bean
public SocketIOServer socketIOServer() {
com.corundumstudio.socketio.Configuration config = new com.corundumstudio.socketio.Configuration();
config.setHostname("localhost");
config.setPort(9094);
SocketIOServer server = new SocketIOServer(config);
return server;
}
/**
* 用于扫描netty-socketio的注解,比如 @OnConnect、@OnEvent
*/
@Bean
public SpringAnnotationScanner springAnnotationScanner() {
return new SpringAnnotationScanner(socketIOServer());
}
}
3.事件处理类
package com.example.demo2;
import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.OnConnect;
import com.corundumstudio.socketio.annotation.OnDisconnect;
import com.corundumstudio.socketio.annotation.OnEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@Component
public class MessageEventHandler {
@Autowired
private SocketIOServer socketIoServer;
//存储SocketIOClient,用于广播
public static ConcurrentMap<String, SocketIOClient> socketIOClientMap = new ConcurrentHashMap<>();
/**
* 客户端连接的时候触发
*
* @param client
*/
@OnConnect
public void onConnect(SocketIOClient client) {
String id = client.getHandshakeData().getSingleUrlParam("id");
//存储SocketIOClient
socketIOClientMap.put(id, client);
//回发消息
client.sendEvent("message", "onConnect back");
System.out.println("客户端:" + client.getSessionId() + "已连接,id=" + id);
}
/**
* 客户端关闭连接时触发
*
* @param client
*/
@OnDisconnect
public void onDisconnect(SocketIOClient client) {
System.out.println("客户端:" + client.getSessionId() + "断开连接");
}
/**
* 客户端事件
*
* @param client 客户端信息
* @param request 请求信息
* @param data 客户端发送数据
*/
@OnEvent(value = "messageevent")
public void onEvent(SocketIOClient client, AckRequest request, Message data) {
System.out.println(data.getName()+"发来消息:" + data.getMsg());
//回发消息
client.sendEvent("messageevent", "我是服务器发来的信息");
//广播消息
sendBroadcast();
}
/**
* 广播消息
*/
public void sendBroadcast() {
for (SocketIOClient client : socketIOClientMap.values()) {
if (client.isChannelOpen()) {
client.sendEvent("Broadcast", "当前时间:" + new Date(System.currentTimeMillis()));
}
}
}
}
4.消息体
package com.example.demo2;
import lombok.Data;
@Data
public class Message {
private String name;
private String msg;
}
5.启动类
package com.example;
import com.corundumstudio.socketio.SocketIOServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
public class DemoApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Autowired
private SocketIOServer socketIOServer;
@Override
public void run(String... args) throws Exception {
socketIOServer.start();
System.out.println("socket.io启动成功!");
}
}
6.前端页面
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, user-scalable=no">
<title>websocket-java-socketio</title>
<script src="https://cdn.bootcss.com/socket.io/2.2.0/socket.io.js"></script>
</head>
<body>
<h1>Socket.io Test</h1>
<div><p id="broadcast">广播区域</p></div>
<div><p id="status">等待连接</p></div>
<div><p id="message">你好!</p></div>
<button id="connect" onClick='connect()'/>Connect</button>
<button id="disconnect" onClick='disconnect()'>Disconnect</button>
<input type="text" id="input">
<button id="send" onClick='send()'/>Send Message</button>
</body>
<script type="text/javascript">
/**
* 前端js的 socket.emit("事件名","参数数据")方法,是触发后端自定义消息事件的时候使用的,
* 前端js的 socket.on("事件名",匿名函数(服务器向客户端发送的数据))为监听服务器端的事件
**/
var socket;
//请求连接
function connect() {
if(socket!=null)return;
socket = io.connect("http://localhost:9094?id=123456")
//监听服务器连接事件
socket.on('connect', function(){ status_update("连接到服务器"); });
//监听服务器关闭服务事件
socket.on('disconnect', function(){ status_update("从服务器中断开"); });
//监听服务器端发送消息事件
socket.on('messageevent', function(data) {
message(data)
});
//监听服务器广播事件
socket.on('Broadcast', function(data) {
Broadcast(data)
});
}
//断开连接
function disconnect() {
socket.disconnect();
socket=null;
}
//显示服务器发来的消息
function message(data) {
document.getElementById('message').innerHTML = "Server says: " + data;
}
//显示当前状态
function status_update(txt){
document.getElementById('status').innerHTML = txt;
}
//显示服务器广播
function Broadcast(data) {
document.getElementById('broadcast').innerHTML = "广播: " + data;
}
//点击发送消息触发
function send() {
var msg = document.getElementById('input').value;
socket.emit('messageevent', {name: '小明', msg: msg});
};
</script>
</html>