当前位置: 首页 > article >正文

Reactor模式

Reactor模式有点类似事件驱动模式。在事件驱动模式中,当有事件触发时,事件源会将事件分发到Handler(处理器),由Handler负责事件处理。Reactor模式中的反应器角色类似于事件驱动
模式中的事件分发器(Dispatcher)角色。
   具体来说,在Reactor模式中有Reactor和Handler两个重要的组件:
(1)Reactor:负责查询IO事件,当检测到一个IO事件时将其发
送给相应的Handler处理器去处理。这里的IO事件就是NIO中选择器查
询出来的通道IO事件。
(2)Handler:与IO事件(或者选择键)绑定,负责IO事件的处
理,完成真正的连接建立、通道的读取、处理业务逻辑、负责将结果
写到通道等。

完整代码:

package com.crazymakercircle.ReactorModel;

import com.crazymakercircle.NioDemoConfig;
import com.crazymakercircle.util.Logger;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

//反应器
class EchoServerReactor implements Runnable {
    Selector selector;
    ServerSocketChannel serverSocket;

    EchoServerReactor() throws IOException {
        //Reactor初始化
        selector = Selector.open();

        serverSocket = ServerSocketChannel.open();

        InetSocketAddress address =
                new InetSocketAddress(NioDemoConfig.SOCKET_SERVER_IP,
                        NioDemoConfig.SOCKET_SERVER_PORT);

        //非阻塞
        serverSocket.configureBlocking(false);


        //分步处理,第一步,接收accept事件
        SelectionKey sk =
                serverSocket.register(selector,0,new AcceptorHandler());

        // SelectionKey.OP_ACCEPT
        serverSocket.socket().bind(address);
        Logger.info("服务端已经开始监听:"+address);


        sk.interestOps(SelectionKey.OP_ACCEPT);

        //attach callback object, AcceptorHandler
        //sk.attach(new AcceptorHandler());
    }

    public void run() {
        try {
            while (!Thread.interrupted()) {

                //io事件的查询
                // 限时阻塞查询
                selector.select(1000);


                Set<SelectionKey> selected = selector.selectedKeys();
                if (null == selected || selected.size() == 0) {
                    continue;
                }
                Iterator<SelectionKey> it = selected.iterator();
                while (it.hasNext()) {
                    //Reactor负责dispatch收到的事件
                    SelectionKey sk = it.next();

                    it.remove();     //避免下次重复处理

                    dispatch(sk);
                }
//                selected.clear();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    void dispatch(SelectionKey sk) {
        Runnable handler = (Runnable) sk.attachment();
        //调用之前attach绑定到选择键的handler处理器对象
        if (handler != null) {
            handler.run();
        }
    }

    // Handler:新连接处理器
    class AcceptorHandler implements Runnable {
        public void run() {
            try {
                SocketChannel channel = serverSocket.accept();
                Logger.info("接收到一个连接");
                if (channel != null)
                    new EchoHandler(selector, channel);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    public static void main(String[] args) throws IOException {
        new Thread(new EchoServerReactor()).start();
    }
}

结果如下:


http://www.kler.cn/news/150323.html

相关文章:

  • 从0开始学习JavaScript--JavaScript 模板字符串的全面应用
  • 【论文学习】机器学习模型安全与隐私研究综述
  • 05_MySQL主从复制架构
  • NX二次开发UF_CURVE_create_joined_feature 函数介绍
  • 重要端口及服务速查
  • docker搭建rabbit集群
  • base64转PDF
  • Debian arm系统安装wxPython
  • ubuntu下训练自己的yolov5数据集
  • C++ 通过CryptoPP计算Hash值
  • 从0开始学习JavaScript--JavaScript 工厂模式
  • Nginx 实现动静资源分离和负载均衡
  • 数据库系统原理——备考计划2:数据库系统的概述
  • EasyRecovery数据恢复软件好不好用?有哪些功能
  • docker 中的–mount 和-v 参数有啥区别
  • gRPC之grpc负载均衡(resolver)
  • 升级openssh以及回滚,telnet远程链接
  • 园区智能配电系统(电力智能监控系统)
  • tomcat调优配置
  • F. Magic Will Save the World
  • CSS3样式详解之圆角、阴影及变形
  • 创建conan包-不同/相同repo中的配方和来源
  • 引领Serverless构建之路,亚马逊云科技re:Invent 2023首日主题演讲重磅发布
  • AIGC: 关于ChatGPT中输出表格/表情/图片/图表这些非文本的方式
  • 移动开发新风向?HarmonyOS、车载、音视频、flutter
  • 精调llama模型
  • Kubernetes之kubeadm集群监控篇—node-exporter部署
  • 优雅退出:避免Spring Boot应用程序在推出JVM时的DestroyJavaVM异常
  • 外汇天眼:外汇市场中的“双向交易”是什么意思?
  • Golang中WebSocket和WSS的支持