`

Nio实现高性能聊天系统

    博客分类:
  • io
阅读更多

本章以建立一个聊天系统为例,介绍如何使用J2SE 1.4非堵塞I/ONI/O)为核心开发一个高性能的实时互动服务器系统,这个高性能服务器系统可以拓展为更广阔的应用,如游戏系统、社区系统或者数据实时采集系统。

 

1.1  系统需求

聊天交流是目前互联网提供的主要内容。聊天系统有多种实现方式,类似ICQ属于一种点对点的聊天系统,还有一种是基于Socket的集中式聊天系统,这种聊天系统需要登录统一的聊天服务器,每个人的聊天信息其他人都可以看到,类似一种会议室,当然,两个人之间也可以进行保密的私语。

在基于Socket的聊天系统中,主要有两种角色:服务器和客户端,不同的客户端登录集中式的服务器,通过服务器将一个客户端发出的信息推送到其他所有客户端。

基于Socket的聊天系统最早实现是使用网页刷新方式,通过客户端不断地自动刷新,将服务器端整个页面内容下载到客户端显示,这种方式的聊天速度慢,而且有刷屏现象,很快被更新的聊天技术所替代。

聊天系统在客户端和服务器之间主要传送的是文字信息,服务器端只需要把最新的文字信息推送到客户端,这样减少了网络传输内容,节省了网络传输的时间,无疑提高了聊天速度。这种“推”技术是目前基于Socket聊天系统的主要实现技术。

一个基于Socket的聊天系统有下列具体功能要求:

1)客户端和服务器必须保持随时随地的连接。这有别于普通Web浏览的连接方式。在使用浏览器访问服务器时,先由客户端发出HTTP协议,然后服务器响应处理这个客户端的响应,再返回处理结果;请求(Request)和响应(Response)是一种一对一的前后因果关系。

而在基于Socket的聊天系统中,客户端发出聊天信息的同时,客户端也在接受服务器发送过来的其他人的聊天信息,因此,请求和响应不存在那种前后对应关系,是两种分别独立进行的进程。

因为服务器任何时候都可能发送信息到客户端,因此,客户端和服务器一旦建立连接,必须能让服务器在以后发送中寻找定位到这个连接。

2)在速度性能方面,聊天系统提出了更高的要求。在网络连接的薄弱环节I/O通信方面,要求能够实现无堵塞地、流畅地数据读写。在面对几百个甚至更多的客户端同时发出连接信息的情况下,服务器要求能够保持高性能的并发处理机制,迅速地完成这几百个并发请求的处理和发送任务。

3)在扩展性和伸缩性方面,聊天系统也提出了一定的要求。当一台服务器不能满足要求时,必须在客户端不知晓的情况下,通过不断增加服务器就能方便地拓展聊天系统的整体处理能力。对于客户端用户来说,这些服务器群都象征一个统一的服务器,不需要他们在进入聊天室之前先选择具体的服务器;也没有单个聊天室最大人数的限制,如果可以,服务器群可以支撑一个巨大容量的聊天室。

1.2  架构设计

本系统的设计核心是Socket底层通信,基于快速稳定的Socket底层通信架构,不但可以实现聊天系统,还可以实现其他如游戏、数据采取等实时性要求较高的系统,甚至可以建立一个快速的平台服务器系统。相比J2EE服务器系统,该平台系统的最大优势就是精简的代码带来的高性能。

当然,如果单纯追求高性能和速度,也许直接使用汇编就可以。使用Java设计这样的实时系统,实际还有一种很重要的目的,即追求高度的可扩展性和伸缩性。

因此,本系统设计必须将高性能和高伸缩性两个方面和谐地统一起来,不能盲目追求性能而破坏面向对象的编程风格和模式;也不能因为追求更大的重用性,建立太多复杂的中间层,其实这方面J2EE已经做得很好,有关J2EE的应用将在以后章节重点讨论。

当然,高性能应该是本系统的主要特色,为了实现本系统高效率的并发处理性能,设计上将采取Reactor模式实现自我快速触发;网络通信上,使用非堵塞I/O进行流畅地数据读写,在应用逻辑上,通过非堵塞的多线程技术实现并发功能处理。特别是J2SE 1.4以后版本推出的非堵塞I/O,将使得Java表现出和C语言同样的优越性能。

1.2.1  Java事件模型

事件只有在被触发时才会发生,它的发生是程序系统无法预料和计划的。例如,火警探测器只有在发生火警时才会触发,但是火警的发生是无法事先预料的,它处于时刻可能发生当中。为了能响应这些无法预料发生的事件,必须建立一套事件处理机制,以预备在发生事件时实现相应的处理。

通常,在一个事件处理框架里有下列3种角色。

·       源目标:事件发生者。

·       监视者:将监察侦听事件的发生,事件发生后,它会被通知到。

·       处理者:事件发生后,它将实现一定的行为动作,也就是处理事件。

Java中有几种模式表达这3种角色之间的关系。

监视模式是一种最常用的模式,GOF《设计模式》中的观察者模式和监视模式类似,这将在以后章节讨论。

在监视模式中,监视者本身也兼任处理者的角色,3种角色被实现为两个独立对象,源目标为一个对象,而监视者和处理者两个角色同位于一个对象中。

例如,一个可视化JavaBean对象Button属于源目标,它通过addActionListener绑定一个监视者对象java.awt.event.ActionListener的子类来完成事件触发机制,当它被用户点按时,ActionListener的子类将完成相应点按事件的处理,如图1-1所示。

nio

1-1  Java GUI中的事件处理

以本系统为例,当用户输入服务器端地址和端口,单击连接按钮后,将启动连接远程服务器线程,其中部分重要方法如下:

connectButton.addActionListener(new ClientFrame_connectButton_actionAdapter(this));

void connectButton_actionPerformed(ActionEvent e) {

        //启动连接服务器线程

        NonBlockingSocket nonBlockingSocket = new NonBlockingSocket(url, port);

        nonBlockingSocket.setDaemon(true);

        nonBlockingSocket.start();

}

连接按钮connectButton通过addActionListener方法加入了一个监视者对象,监视者ClientFrame_connectButton_actionAdapter代码如下:

class ClientFrame_connectButton_actionAdapter

implements java.awt.event.ActionListener {

  ClientFrame adaptee;

  ClientFrame_connectButton_actionAdapter(ClientFrame adaptee) {

    this.adaptee = adaptee;

  }

  public void actionPerformed(ActionEvent e) {

    adaptee.connectButton_actionPerformed(e);

  }

}

<iframe id="cproIframe_369316_1" src="http://cb.baidu.com/ecom?adn=4&amp;at=231&amp;aurl=&amp;cad=1&amp;ccd=24&amp;cec=UTF-8&amp;cfv=17&amp;ch=0&amp;col=zh-CN&amp;conOP=0&amp;cpa=1&amp;dai=1&amp;dis=0&amp;ltr=http%3A%2F%2Fwww.jdon.com%2Fconcurrent%2Freactor.htm&amp;ltu=http%3A%2F%2Fwww.jdon.com%2Fconcurrent%2Fniochat1.html&amp;lunum=6&amp;n=banq_cpr&amp;pcs=1349x599&amp;pis=10000x10000&amp;ps=3227x186&amp;psr=1366x768&amp;pss=1349x6233&amp;qn=c360a086666e71d3&amp;rad=&amp;rs=300&amp;rsi0=336&amp;rsi1=280&amp;rsi5=4&amp;rss0=%23FFFFFF&amp;rss1=%23F7F7F7&amp;rss2=%23003366&amp;rss3=%23003366&amp;rss4=%23008000&amp;rss5=&amp;rss6=%23e10900&amp;rss7=&amp;scale=&amp;skin=&amp;td_id=9223372032564280291&amp;tn=text_default_336_280&amp;tpr=1426822558741&amp;ts=1&amp;xuanting=0&amp;dtm=BAIDU_DUP2_SETJSONADSLOT&amp;dc=2&amp;di=369316" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" align="center,center" width="336" height="280"></iframe>

上述代码中,通过适配器模式将事件处理委托源目标实现,这就产生了第二种事件处理模式——委托模式。

委托模式使源目标、监视者和处理者3种角色各自实现为独立的3个对象,在这3个对象之间传输的是事件,这个模式在系统复杂时会经常使用,例如在J2EEB/S架构中,前台JSP的表单提交事件后,由MVC模式中的Servlet获得事件数据,经过简单封装成事件对象后,委托给后台EJB层实现进一步处理,如图1-2所示。

1-2中,客户端浏览器将表单事件直接提交到服务器端的JSP/ServletsJSP/Servlets作为事件的监视者,接收到事件后,并不对事件立即进行处理,而是委托给JavaBeans/EJB进行复杂的逻辑或运算处理。

nio

1-2  B/S多层结构委托模式

以上两种模式特点是至少有两个对象分别代表事件的3个角色,而在Reactor模式中,则是在一个对象中绑定了这3种角色,Reactor的意思是自我触发、自主激活的意思。

J2SE 1.4版本中的新特性非堵塞I/ONonblocking I/O)提供了基于Reactor模式的实现,这大大简化了基于Socket的应用和编程,如图1-3所示。

nio

1-3  Reactor模式

在非堵塞I/O API监视器是其一个重要的类Selector被监视的源目标是可以被Selector联系的SelectableChannel基本也属于Selector的相关部分),事件类型有是否有接受的连接OP_ACCEPT、是否可以连接OP_CONNECT、是否可以读取OP_READ和是否可以写入OP_WRITE

监视器Selector主要是监视这些事件,一旦发生,生成SelectionKey对象,Selector是自我触发、自我激活的,因此是典型的Reactor模式实现,其原理将在后面章节详细讨论。

但是,在非堵塞I/O API中,并不是由Selector来实现事件的处理,事件处理是由Selector激活出来后,通过其他处理器Handler来实现处理,开发者使用非堵塞I/O API需要做的工作就是:获取Selector激发的事件,然后根据相应事件类型,编制自己的处理器代码来进行具体处理。例如,如果是可读取事件,那么编制代码从SelectableChannel读取数据包,然后处理这个数据包。

在非堵塞I/O API中,使用Reactor模式将事件发生和事件处理两个部分实现分离解耦,事件发生部分只负责事件的激活,而事件处理由专门的处理器实现具体处理。

分享到:
评论

相关推荐

    基于nio的简易聊天室

    在Java编程领域,NIO(New Input/Output)是一个重要的概念,它提供了非阻塞I/O操作的能力,相比传统的BIO(Blocking I/O),在处理大量并发连接时表现出更高的效率和性能。本项目"基于nio的简易聊天室"旨在通过NIO...

    UDP NIO聊天系统

    总之,UDP NIO聊天系统结合了UDP的高效传输特性和NIO的非阻塞I/O优势,实现了高性能的多人实时聊天功能。在实际开发中,需要注意处理可能出现的网络异常、数据包丢失等问题,以确保系统的稳定性和可靠性。

    用Netty实现NIO Socket聊天系统示例

    在本示例中,我们将深入探讨如何利用Netty实现一个基于NIO(非阻塞I/O)的Socket聊天系统。NIO是一种I/O模型,它允许Java程序在不阻塞线程的情况下处理多个输入/输出流,从而提高并发性能。 首先,Netty的核心组件...

    基于NIO简单实现网络聊天功能

    Java NIO(New IO)是Java 1.4版本引入的一种新的IO API,用来替代标准的Java IO API。...以上就是基于NIO实现网络聊天功能的关键技术点,通过这种方式,可以构建出一个高效、并发能力强的网络聊天系统。

    java NIO socket聊天

    总的来说,Java NIO通过非阻塞I/O、多路复用和高效的缓冲区机制,为开发高性能、高并发的网络应用提供了强大的支持。在设计聊天服务器时,利用NIO可以有效地处理大量并发用户,降低CPU压力,提高系统整体性能。同时...

    java nio 聊天室源码

    在这个“java nio 聊天室源码”项目中,开发者使用了NIO来构建一个聊天室应用,以实现用户之间的实时通信。 1. **Java NIO基础** - **通道(Channel)**:在NIO中,数据是通过通道进行传输的,如SocketChannel、...

    基于NIO非阻塞的java聊天demo(支持单聊和群聊)

    总之,这个基于NIO非阻塞的Java聊天demo展示了如何利用Java NIO来构建一个高并发、低延迟的聊天系统。它不仅涉及到网络编程的基础知识,如套接字通信,还涵盖了多线程、并发控制以及高效数据传输的技巧,是学习和...

    基于NIO的聊天室

    在Java编程领域,NIO...通过以上分析,我们可以看到,基于NIO的聊天室利用了Java NIO的高效特性,实现了多客户端并发连接,提升了系统的整体性能。这个项目对于理解和掌握Java NIO的概念和实战具有很好的实践价值。

    基于聊天系统的编程实现

    8. **性能优化**:对于大规模聊天系统,优化网络带宽使用、减少延迟、提高并发处理能力都是必要的。 总之,“基于聊天系统的编程实现”涵盖了网络编程、协议选择、用户交互、数据处理等多个技术领域。通过深入理解...

    高性能网络编程必备技能之IO与NIO阻塞分析

    在IT行业中,网络编程是构建分布式系统和网络应用的基础,而高效的网络编程则直接关系到系统的性能...在实际项目中,结合多线程、线程池和适当的并发控制策略,可以更好地发挥IO和NIO的优势,构建出高性能的网络服务。

    基于java NIO的简单聊天软件示例

    JAVA NIO有两种解释:一种叫非阻塞IO(Non-blocking I/O),另一种也叫新的IO(New I/O),其实是同一个概念。它是一种同步非阻塞的I/O模型,也是...本例是使用java nio实现的简单聊天系统,界面简单,旨在学习java nio

    websocket netty实现的简单聊天系统

    Netty则是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。它提供了一种高效的方式来处理I/O事件,通过非阻塞I/O模型(NIO)和事件驱动架构,Netty能够有效地利用系统...

    实现简单即时通讯聊天系统、spring boot + mvc + mybatis + netty-sokey.io.zip

    本项目是一个基于Spring Boot、Spring MVC、MyBatis和Netty的简单即时通讯聊天系统实现。这个系统的设计和实现涵盖了多个关键的Java技术栈,包括Web开发、持久化框架和网络通信,对于学习和理解现代Java后端架构具有...

    使用NIO实现非阻塞socket通信

    本项目利用NIO实现了一个简单的非阻塞socket通信的聊天工具,使得在高并发环境下,服务器能够同时处理多个客户端连接,提高系统性能。 1. **非阻塞I/O**: 在BIO模型中,读写操作是阻塞的,即当没有数据可读或无法...

    Java实现C/S架构聊天系统

    在高并发的聊天系统中,服务器端需要同时处理大量客户端的连接,NIO的非阻塞特性使得服务器可以同时处理多个客户端请求,而无需为每个连接创建一个新的线程,从而节省了系统资源。 多线程IO操作在聊天系统中同样至...

    多线程精品资源--Java NIO+多线程实现聊天室.zip

    在Java编程中,多线程和非阻塞I/O(NIO)是两个核心概念,它们在构建高性能、高并发的应用程序中起着至关重要的作用。在这个“多线程精品资源--Java NIO+多线程实现聊天室”的压缩包中,我们可以推测它包含了一套...

    网络聊天系统有单独的客户端,服务器端。该聊天系统实现图形界面下的聊天功能

    为了实现实时通信,聊天系统通常采用TCP协议,因为它提供可靠的数据传输,确保消息的顺序和完整性。不过,考虑到实时性需求,UDP协议也可以结合使用,比如用于音视频通话。心跳机制是维持客户端与服务器连接的关键,...

    android-socket-nio-master.zip

    传统的Socket通信通常基于BIO(Blocking I/O)模型,但随着高性能和高并发需求的增加,开发者开始转向NIO(Non-blocking I/O)模型。"android-socket-nio-master.zip" 是一个关于Android中使用Socket结合NIO实现高效...

    基于SpringBoot+Vue的聊天系统.zip

    Netty 提供异步的、基于事件驱动的网络应用程序框架,用以快速开发高性能、高可靠性的网络 IO 程序,是目前最流行的 NIO 框架。 本系统基于适合有一定基础的大学生! 运行说明:本系统已经开源,感兴趣自行下载运行...

    java聊天系统局域网聊天系统

    Java聊天系统是一款基于Java编程语言实现的通信应用,主要用于在局域网环境下提供实时的文本、语音甚至视频聊天功能。这种系统通常采用客户端-服务器架构,允许用户在同一个网络内的不同设备上进行交互。下面将详细...

Global site tag (gtag.js) - Google Analytics