• netty-socketio 概述


    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
    

    点击网页按钮

  • 相关阅读:
    MySql中启用InnoDB数据引擎的方法
    云说的到底对不对,京东到底行不行?
    hibernate HQL查询的参数绑定
    MySQL到底能支持多大的数据量?
    C# RSA和Java RSA互通
    Log4j 2使用教程
    Log4j.properties配置详解
    JMX 基础Demo
    iBatis缓存实现源码分析-FIFO,LUR实现方法
    SqlMapClient 创建过程之SqlMapConfigParser源码走读
  • 原文地址:https://www.cnblogs.com/pomer-huang/p/netty-socketio.html
Copyright © 2020-2023  润新知