6. 消息中心的设计与细节

1.使用场景:

优惠券的倒计时提醒,消息推送,聊天,这些都是客户端主动的发送消息给服务器与服务器在发送到服务端的场景。 在不使用协议技术的情况下现在的机制都是一请求一响应(就是前端一请求后台响应);现在整个网络都是构建在 tcp 长链接 可靠协议(有3次握手),和udp不可靠协议(没有3次握手):tcp长链接,响应之后链路不会断开但是服务端或者客户端只要有一方断开这个链路就会断开; http是短链接:一请求一响应链路断开 java中对 tcp 的方案:bio (同步阻塞式io), nio (异步非阻塞式io)api及其复杂,netty对nio进行了封装一般都用netty。那这个netty该怎么实现了,要知道这个netty是传输层的我们是无法自己操作传输层的东西,只能操作应用层的技术要知道http也是应用层的技术就像我们访问百度得写上百度的网址。

2.bio实现点对点发送消息:

为什么main方法开了一个线程,又要开一个线程专门接受消息因为为了实现双方想发多少消息都可以,如果只有一个main方法的主线程那么只会a发送一个消息b一定要接收才能发送消息。但是这也是bio最致命的问题,因为每一个客户端都得开一个线程,但是线程是服务器最宝贵的资源,开这个线程主要目的就是解决read这个阻塞式的方法带来的不便,如果不开这个线程假如我有3个客户端1、2、3,我服务器发送消息给2就必须经过1,不能直接发送到2客户端

2.1服务端

public class Server {

    public static void main(String[] args) throws IOException {

        //创建Socket服务对象
        ServerSocket serverSocket = new ServerSocket(8888);
        //服务端要接收客户端的连接 - 阻塞式的
        final Socket socket = serverSocket.accept();//一旦有客户端连接,该方法就会返回连接该客户端的Socket对象,如果没有客户端连接,就会一直阻塞
        System.out.println("有一个客户端连接!");

        Scanner scanner = new Scanner(System.in);

        //开了一个子线程监听客户端的发送消息
        new Thread(){
            @Override
            public void run() {
                while(true) {
                    //获得客户端的请求
                    try {
                        InputStream in = socket.getInputStream();
                        byte[] bytes = new byte[10 * 1024];
                        int len = 0;//read方法是一个阻塞式的方法,如果没有客户端的消息,线程会阻塞在该方法上
                        len = in.read(bytes);
                        System.out.println("获取到客户端的请求数据:" + new String(bytes, 0, len));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();


        while (true) {

            //返回客户端的响应
            System.out.println("请输入发送的内容:");
            String content = scanner.next();
            OutputStream out = socket.getOutputStream();
            out.write(content.getBytes());
        }

    }
}

2.2 客户端

public class Client {

    public static void main(String[] args) throws IOException {
        //创建客户端的socket对象,并且连接服务器
        final Socket socket = new Socket("127.0.0.1", 8888);

        Scanner scanner = new Scanner(System.in);

        //开启子线程接收服务器的响应
        new Thread(){
            @Override
            public void run() {
                while(true) {
                    //接收响应
                    InputStream in = null;
                    try {
                        in = socket.getInputStream();
                        byte[] bytes = new byte[10 * 1024];
                        int len = in.read(bytes);
                        System.out.println("接收到服务器的响应:" + new String(bytes, 0, len));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();

        while (true) {
            //发消息
            System.out.println("请输入发送的内容:");
            String content = scanner.next();
            OutputStream out = socket.getOutputStream();
            out.write(content.getBytes());
            out.flush();
        }
    }
}

3.NIO的介绍与使用

他与bio最大的区别是多了一个Selector (多路复用器),ServerSocketChannel
(服务端,接收客户端的连接),SocketChannel (连接对象)。ServerSocketChannel 注册到Selector
我们可以写一个主线程,死循环监听多路复用器,如果有客户端连接,主线程就能通过多路复用器知道,然后处理新的连接,如果监听到客户端发送的消息则多路复用器通过循环告知主线程,主线程只需要处理该客户端的消息即可。也就是说每一个客户端都是一个SocketChannel, 然后注册到Selector ,也只有一个线程工作。redis只所以单线程还能处理那么多客户端的命令就是因为底层就是用了多路复用器的原理

4.ByteBuffer - NIO数据传递的对象,本质还是Byte数组

他分为:容量 - byte数组的大小 位置 - byte数组读写到的地方 界限 - byte数组不可读写的位置
写的时候:假如写到三分之一,位置就会到3分之一,界限在容量的位置上;读的时候位置回到原点,界限到3分之一的位置,每读一点位置移一点一直到界限的位置。

5.Netty的基本使用

  • Netty的线程模型
  • 1、单线程模型 - 1个线程处理所有客户端的连接和数据读取
  • 2、多线程模型 - 1个线程处理客户端的连接、线程池处理客户端数据的读写
  • 3、主从线程池模型 - 主线程池处理客户端的连接、从线程池处理客户端数据的读写
    单线程基本不用,一般服务端用主从线程池模型,客户端用多线程模型

6.Netty对WebSocket协议的支持

什么是WebSocket协议?
WebSocket是一种基于TCP协议的长连接协议,简单来说,就是客户端和服务器可以随意发送消息。
优势:可以直接在浏览器和服务器之间构建长连接(也支持程序和程序之间构建长连接)
在这里插入图片描述
7.Netty集群的搭建:
我们可以利用zookeeper做一个注册中心netty的地址都放在zookeeper中,浏览器通过访问发现服务于发现服务去获得zookeeper的netty地址,并且把这些缓存起来,毕竟这些地址一般很少变。
在这里插入图片描述
8.Netty服务器Channel管理的方案:
现在我要服务器主动发送消息给客户端,那服务器怎么知道客户端谁是谁,在第一次客户端发送消息的时候就把用户id和设备id给注册到服务器用map保存起来。
在这里插入图片描述
9.Netty集群发行消息的方案:
现在netty是一个集群,客户端会随机的连上某台服务器,现在有一个服务器要发送消息给小明,可以通过mq所有的netty去订阅mq的消息是小明就连接,如果不通过mq压根就不知道会消息会给谁
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个用于企业内部消息转发的消息平台软件详细设计文档模板: # 软件详细设计文档 ## 1. 引言 ### 1.1 目的 本文档旨在描述企业内部消息转发的消息平台软件的详细设计,包括软件结构、模块设计和数据存储等方面的内容。 ### 1.2 范围 本文档适用于企业内部消息转发的消息平台软件的详细设计,包括但不限于以下方面: - 软件结构设计 - 模块设计 - 数据存储设计 ### 1.3 参考资料 - 软件需求规格说明书 - 系统架构设计文档 ## 2. 软件结构设计 ### 2.1 架构图 描述软件的整体架构,包括所有系统组件之间的关系。 ### 2.2 组件说明 描述每个系统组件的职责和功能。 ### 2.3 接口定义 描述组件之间的接口,包括输入输出参数和调用规则等。 ## 3. 模块设计 ### 3.1 模块列表 列出所有模块的名称和功能。 ### 3.2 模块接口定义 描述每个模块的输入和输出参数,以及调用规则。 ### 3.3 模块流程图 描述每个模块的流程,包括输入、处理和输出。 ## 4. 数据存储设计 ### 4.1 数据库设计 描述数据库的表结构和关系。 ### 4.2 数据库接口定义 描述数据库接口,包括输入输出参数和调用规则等。 ## 5. 系统测试 ### 5.1 测试用例 列出所有测试用例,包括输入数据和期望输出结果。 ### 5.2 测试结果 记录每个测试用例的实际输出结果。 ## 6. 总结 本文档详细描述了企业内部消息转发的消息平台软件的设计细节,包括软件结构、模块设计和数据存储等方面。此外,还提供了系统测试的测试用例和测试结果。该文档可作为软件开发和测试的参考依据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值