• 基于XSocket框架的socket编程技巧(设置连接的超时时间和最大空闲时间)


    基于XSocket框架的socket编程技巧(同步通信)

    最近在做socket通信编程,现总结如下,关于XSocket的大话就不再多说了,google一下一大片。

    一、  Server端

    Socket监听如下:

    ServerHandler handler = new ServerHandler();

    //创建一个服务端的对象  

    IServer srv = new Server(address, port, handler);

    //设置当前的采用的异步模式  

    srv.setFlushmode(FlushMode.ASYNC);

    //设置连接的超时时间和最大空闲时间

    srv.setConnectionTimeoutMillis(5000);

    srv.setIdleTimeoutMillis(10000);

    //启动监听

    srv.start();

    其中如下两个方法的设置与ServerHandler的实现有关系,

    srv.setConnectionTimeoutMillis(5000);

    srv.setIdleTimeoutMillis(10000);

    下面再看ServerHandler吧

    publicclass ServerHandler implements IDataHandler, IConnectHandler,

        IIdleTimeoutHandler, IConnectionTimeoutHandler, IDisconnectHandler

    {

      publicboolean onConnect(INonBlockingConnection nbc) throws IOException,

          BufferUnderflowException, MaxReadSizeExceededException

      {

        returntrue;

      }

      publicboolean onDisconnect(INonBlockingConnection nbc) throws IOException

      {

        returntrue;

     

      publicboolean onData(INonBlockingConnection nbc) throws IOException,

          BufferUnderflowException, ClosedChannelException,

          MaxReadSizeExceededException

      {

        returntrue;

      }

      publicboolean onIdleTimeout(INonBlockingConnection connection)

          throws IOException

      {  

          System.out.println("onIdleTimeout");

        returnfalse;

      }

      publicboolean onConnectionTimeout(INonBlockingConnection connection)

          throws IOException

      {

          System.out.println("onConnectionTimeout");

        returntrue;

      }

    ServerHandler分别实现了以下接口

    IDataHandler, IConnectHandler,IIdleTimeoutHandler, IConnectionTimeoutHandler, IDisconnectHandler

    其中主要说一下IDataHandlerIIdleTimeoutHandlerIConnectionTimeoutHandler吧。

     

    首先说明一下,socket连接的生命周期与server端的connectionTimeoutidleTimeoutclient端有关系。

     

    A、 IDataHandler中的事件onData事件就是处理业务逻辑的,当客户端发送一个业务请求时,会触发此事件。

    B、 IIdleTimeoutHandler中的onIdleTimeout事件是在socket连接空闲超时被触发,这个超时时间就是刚刚srv.setIdleTimeoutMillis(10000)设置的值“10000”,单位毫秒。此事件返回一个bool状态,

      (1)   如果返回truexsocket则认为这事件已经关闭了此连接,那么我们在此事件中是否去关闭连接了呢?前面说了这个连接的生命周期和与server端的connectionTimeoutidleTimeoutclient端有关,如下解释,

    1)、如果close();,那么就不多说了;

    2)、如果没有close();,此时又和IConnectionTimeoutHandler的事件onConnectionTimeoutclient有关。如果onConnectionTimeout返回false,则此事件被触发并在事件结束后,则xsocket关闭连接;如果onConnectionTimeout返回true,则此连接由client负责关闭。

      (2)   如果返回false,相当于onIdleTimeout没有做任何处理,则此时又和IConnectionTimeoutHandler的事件onConnectionTimeout有关。如果onConnectionTimeout事件返回true,则onIdleTimeout事件被触发并在事件结束后由xsocket关闭连接;如果onConnectionTimeout事件返回false,则onConnectionTimeoutonIdleTimeout任何一个事件被触发后就会由xsocket关闭连接。

    C、 IConnectionTimeoutHandler中的onConnectionTimeout事件是在socket建立连接后,经过srv.setConnectionTimeoutMillis(5000)这个方法中的值时间后触发此事件,强调是指建立连接时,不是指上一次通信时间。此事件返回一个bool状态:

     

      (1)   如果返回true,如下解释,

    IIdleTimeoutHandler的事件onIdleTimeoutclient有关。如果onIdleTimeout返回false,则在onIdleTimeout事件被触发并在事件结束后,则xsocket关闭连接;如果onIdleTimeout返回true,则此连接由client负责关闭。

      (2)   如果返回false,解释如下:

    IIdleTimeoutHandler的事件onIdleTimeout有关。如果onIdleTimeout事件返回true,则onConnectionTimeout事件被触发并在事件结束后由xsocket关闭连接;如果onIdleTimeout事件返回false,则onConnectionTimeoutonIdleTimeout任何一个事件被触发后就会由xsocket关闭连接。

     

    终上,关于在服务器端socket连接的生命周期如下表(以下事件中都没有通过编程主动关闭连接):

     

    onIdleTimeout

    返回值

    onConnectionTimeout

    返回值

    何时关闭

    true

    true

    client端负责

    false

    true

    idleTimeout到时

    true

    false

    connectionTimeout到时

    false

    false

    idleTimeoutconnectionTimeout的最小值到达时

     

    说明一下connectionTimeoutidleTimeout从何时开始计时:

    connectionTimeout是从建立连接开始计时;

    idleTimeout是从建立连接或最后一次触发onData事件时开始计时;

     

     

    二、  Client端

    1、如何创建一个同步socket连接?

       A、 可以通过直接new 一个BlockingConnection(String hostname, int port)

       B、 也可通过异步连接构建,如new BlockingConnection(INonBlockingConnection delegate)

    2、当然XSocket也提供了连接池,同样包括同步连接池和异步连接池。

    BlockingConnectionPool pool = new BlockingConnectionPool();这样就创建了一个同步连接池,既然是池,肯定会有池的大小了,pool.setMaxActivePerServer(poolSize);这是为池设置每个server池的大小,也可以设置池的总大小,如果不设置,默认为值为Integer.MAX_VALUE

     

    如何从池中获取一个连接呢,如IBlockingConnection bc = pool.getBlockingConnection(host,port);有很多重载方法了。

    当获取这个连接之后,我们可以通过设置如下参数进行调整优化:

     

    设置连接超时时间

    bc.setConnectionTimeoutMillis(connectTimeoutMillis);

    设置连接最大空闲时间

    bc.setIdleTimeoutMillis(this.idleTimeoutMillis);

    是否自动刷新缓存

    bc.setAutoflush(false);

    这项时设置在真正要关闭连接时,client端是否要立即释放随机分配的端口,默认不会立即释放端口,需要等待1~4分钟,连接一直处于TIME_WAIT状态,如果这样设置,当关闭连接时,就会立即释放端口。

    bc.setOption(IBlockingConnection.SO_LINGER, "0");

     

    当然当连接使用完以后,需要调用bc.close();放回连接池中,如果close失败,那就要调用pool.destroy(bc)真正的关闭连接了。

     

    仍需要解释下这里的connectTimeoutMillisidleTimeoutMillis了,

    connectTimeoutMillis是池中获取连接开始算起的;

    idleTimeoutMillis是在调用close方法后开始算起的;

     

    client端连接的生命周期为connectTimeoutMillisidleTimeoutMillis的最小值。

  • 相关阅读:
    SpringMVC配置双数据源,一个java项目同时连接两个数据库
    Jquery EasyUI封装简化操作
    C#中Math.Round()实现中国式四舍五入
    Entity Framework6 with Oracle
    在C#中如何读取枚举值的描述属性
    MVC视图中处理Json
    ASP.NET MVC中实现多个按钮提交的几种方法
    asp.net MVC的EF与easyui DataGrid数据绑定
    idea maven下载包太慢了如何解决
    ssh报错No operations allowed after connection closed.Connection was implicitly clos
  • 原文地址:https://www.cnblogs.com/cuker919/p/4878529.html
Copyright © 2020-2023  润新知