文章正文

网站客服-netty-socketio

【文章】2021-04-24

简介网站客服-netty-socketio

netty-socketio是一个开源的Socket.io服务器端的一个java的实现,它基于Netty框架,可用于服务端推送消息给客户端。

说到服务端推送技术,一般会涉及WebSocket,WebSocket是HTML5最新提出的规范,虽然主流浏览器都已经支持,但仍然可能有不兼容的情况,为了兼容所有浏览器,给程序员提供一致的编程体验,SocketIO将WebSocket、AJAX和其它的通信方式全部封装成了统一的通信接口,也就是说,使用SocketIO时不用担心兼容问题,底层会自动选用最佳的通信方式。

netty-socketio 框架事件流程

netty-socketio 示例demo

pom.xml

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.corundumstudio.socketio</groupId>
        <artifactId>netty-socketio</artifactId>
        <version>1.7.17</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.4</version>
        <scope>provided</scope>
    </dependency>
 </dependencies>

启动类 NettySocketioApplication

@SpringBootApplication
@Slf4j
public class NettySocketioApplication implements CommandLineRunner {    
        public static void main(String[] args) {
        SpringApplication.run(NettySocketioApplication.class, args);
    }        
    @Autowired
    private SocketIOServer socketIOServer;    
    @Override
    public void run(String... strings) {
        socketIOServer.start();
        log.info("socket.io启动成功!");
    }
}

Message

@Data
public class Message {    
    private String msg;
}

配置类 NettySocketioConfig

@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(9092);

        SocketIOServer server = new SocketIOServer(config);        
        return server;
    }    
    /**
     * 用于扫描netty-socketio的注解,比如 @OnConnect、@OnEvent
     */
    @Bean
    public SpringAnnotationScanner springAnnotationScanner() {        
        return new SpringAnnotationScanner(socketIOServer());
    }
}

消息处理器 MessageEventHandler

@Component
@Slf4j
public class MessageEventHandler {    
        @Autowired
    private SocketIOServer socketIoServer;    
    public static ConcurrentMap<String, SocketIOClient> socketIOClientMap = new ConcurrentHashMap<>();    
    /**
     * 客户端连接的时候触发
     *
     * @param client
     */
    @OnConnect
    public void onConnect(SocketIOClient client) {        
    String mac = client.getHandshakeData().getSingleUrlParam("mac");        
            //存储SocketIOClient,用于发送消息
        socketIOClientMap.put(mac, client);        
        //回发消息
        client.sendEvent("message", "onConnect back");
        log.info("客户端:" + client.getSessionId() + "已连接,mac=" + mac);
    }    
    /**
     * 客户端关闭连接时触发
     *
     * @param client
     */
    @OnDisconnect
    public void onDisconnect(SocketIOClient client) {
        log.info("客户端:" + client.getSessionId() + "断开连接");
    }    
    /**
     * 客户端事件
     *
     * @param client   客户端信息
     * @param request 请求信息
     * @param data     客户端发送数据
     */
    @OnEvent(value = "messageevent")    
    public void onEvent(SocketIOClient client, AckRequest request, Message data) {
        log.info("发来消息:" + data);        
        //回发消息
        client.sendEvent("messageevent", "我是服务器都安发送的信息");        
        //广播消息
        sendBroadcast();
    }    
    /**
     * 广播消息
     */
    public void sendBroadcast() {        
            for (SocketIOClient client : socketIOClientMap.values()) {            
                    if (client.isChannelOpen()) {
                client.sendEvent("Broadcast", "当前时间", System.currentTimeMillis());
            }
        }

    }
}

html 页面

<!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="status">Waiting for input</p></div><div><p id="message">hello world!</p></div><button id="connect" onClick='connect()'/>Connect</button><button id="disconnect" onClick='disconnect()'>Disconnect</button><button id="send" onClick='send()'/>Send Message</button></body><script type="text/javascript">

    /**
     * 前端js的 socket.emit("事件名","参数数据")方法,是触发后端自定义消息事件的时候使用的,
     * 前端js的 socket.on("事件名",匿名函数(服务器向客户端发送的数据))为监听服务器端的事件
     **/
    var socket = io.connect("http://localhost:9092?mac=2");    var firstconnect = true;    
    
    function connect() {        
            if(firstconnect) {            
                    //socket.on('reconnect', function(){ status_update("Reconnected to Server"); });
            //socket.on('reconnecting', function( nextRetry ){ status_update("Reconnecting in "
            //+ nextRetry + " seconds"); });
            //socket.on('reconnect_failed', function(){ message("Reconnect Failed"); });
            //firstconnect = false;
        } else {
            socket.socket.reconnect();
        }
    }    
    //监听服务器连接事件
    socket.on('connect', function(){ status_update("Connected to Server"); });    
    //监听服务器关闭服务事件
    socket.on('disconnect', function(){ status_update("Disconnected from Server"); });    
    //监听服务器端发送消息事件
    socket.on('messageevent', function(data) {
        message(data)        
        //console.log("服务器发送的消息是:"+data);
    });    
    //断开连接
    function disconnect() {
        socket.disconnect();
    }    
    function message(data) {        
        document.getElementById('message').innerHTML = "Server says: " + data;
    }    
    function status_update(txt){        
        document.getElementById('status').innerHTML = txt;
    }    
    function esc(msg){        
        return msg.replace(/</g, '<').replace(/>/g, '>');
    }    
    //点击发送消息触发
    function send() {        
            console.log("点击了发送消息,开始向服务器发送消息")        
            var msg = "我很好的,是的.";
        socket.emit('messageevent', {msgContent: msg});
    };
</script>
</html>

执行输出

运行 SpringBoot 服务器

>  mvn spring-boot:run

点击网页按钮

打赏支持

感谢您的支持,加油!

打开微信扫码打赏,你说多少就多少

找书费时,联系客服快速查找!

扫码支持

在线客服8:30-22:30,若离线请留言!

获取教程,请联系在线客服!

扫码支持

在线客服8:30-22:30,若离线请留言!

热门阅读

找PDF电子书,太费时间?

  • 微信扫描二维码,让客服快速查找。
  • 在线客服8:30-22:00,若离线请留言!