好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

使用Beetle.Express简单构建高吞吐的TCP&UDP应用

使用Beetle.Express简单构建高吞吐的TCP&UDP应用

使用Beetle.Express简单构建高吞吐的TCP&UDP应用

在Beetle.Express1.2中加了UDP支持,而整体的设计结构也做了调整.只需要通过简单的配置就能实现高吐的TCP&UDP应用.由于组件引用UDP服务同样也支持会话状态所以对于服务是TCP或UDP对使用者来说完全是透明的.使用者只需要关心以下几个接口即可:IServer(服务描述接口),IChannel(通道会话),IData(发送数据描述),IReceiveData(数据接收描述)和IServerHandler(服务处理接口).而使用在使用组件的时候只需要实现 IServerHandler.

ISer v erHandler

该接口主要用于描述相关服务的工作,包括连接接入,连接释放,数据接收,数据发送完成和处理错误等过程.

?

/// <summary>

     /// 服务处理描述接口

     /// </summary>

     public   interface   IServerHandler

     {

         /// <summary>

         /// 连接创建处理过程

         /// </summary>

         /// <param name="server">对应的Tcp&UDP服务对象</param><br>        /// <param name="e">连接详细信息</param>

         void   Connect(IServer server, ChannelConnectEventArgs e);

         /// <summary>

         /// 连接断开处理过程

         /// </summary>

         /// <param name="server">对应的Tcp&UDP服务对象</param><br>        /// <param name="e">连接详细信息</param>

         void   Disposed(IServer server, ChannelEventArgs e);

         /// <summary>

         /// 错误处理过程

         /// </summary>

         /// <param name="server">对应的Tcp&UDP服务对象</param>

         /// <param name="e">详细错误信息</param>

         void   Error(IServer server, ErrorEventArgs e);

         /// <summary>

         /// 数据接收处理过程

         /// </summary>

         /// <param name="server">对应的Tcp&UDP服务对象</param>

         /// <param name="e">接收数据详细信息</param>

         void   Receive(IServer server, ChannelReceiveEventArgs e);

         /// <summary>

         /// 数据发送情况处理过程

         /// </summary>

         /// <param name="server">对应的Tcp&UDP服务对象</param><br>        /// <param name="e">数据发送状态信息</param>

         void   SendCompleted(IServer server, ChannelSendEventArgs e);

 

         

     }

使用Beetle.Express构建TCP或UDP服务,只实现以上接口即可.完全不需要其他工作.

?

class   Program:IServerHandler

     {

          

 

         public   void   Connect(IServer server, ChannelConnectEventArgs e)

         {

             Console.WriteLine( "{0} connected  @{1}" , e.Channel.EndPoint,server.Name);

             

         }

 

         public   void   Disposed(IServer server, ChannelEventArgs e)

         {

             Console.WriteLine( "{0} disposed" , e.Channel.EndPoint);

         }

 

         public   void   Error(IServer server, ErrorEventArgs e)

         {

             Console.WriteLine( "{0} error:{1}" , e.Channel.EndPoint, e.Error.Message);

             

         }

 

         public   void   Receive(IServer server, ChannelReceiveEventArgs e)

         {         

             string   command = e.Data.ToString(Encoding.UTF8);

             Console.WriteLine( "receive:{0}\t@{1}" ,command,server.Name);

             Data data = new   Data(64);

             data.Write(server.Name, Encoding.UTF8);

             server.Send(data, e.Channel);

         }

         public   void   SendCompleted(IServer server, ChannelSendEventArgs e)

         {

              

         }

     }

以上是实现一个网络处理服务,对以上代码来说可以是一个TCP服务也可以是一个UDP服务.由于 IServerHandler统一管理服务处理,因此这个实现是TCP或UDP服务取决于 ServerFactory加载的配置信息.实际上可以N个TCP服务和UDP服务同时绑定到该Handler上.  

 绑定服务

 组件是通过配置来描服务,可以同时描述多个TCP和UDP服务,下以配置在同一 IServerHandler上同量启动TCP和UDP服务.

?

<? xml   version = "1.0" ?>

< configuration >

   < configSections >

     < section   name = "serverSection"   type = "Beetle.Express.ServerSection, Beetle.Express" />

   </ configSections >

   < serverSection   xmlns = "urn:Beetle.Express" >

     < listens >

       < add   name = "TEST_TCP"   type = "TCP"   port = "8088"   handler = "Beetle.Express.Sample.Program,Beetle.Express.Sample" />

      < add   name = "TEST_UDP"   type = "UDP"   port = "8089"   handler = "Beetle.Express.Sample.Program,Beetle.Express.Sample" />  

  </ listens >

   </ serverSection >

< startup >< supportedRuntime   version = "v4.0"   sku = ".NETFramework,Version=v4.0" /></ startup ></ configuration >

 以上配置是在同一个handler上分别在8088端口上打开TCP服务和在8089打开UDP服务.配置完成后只需要 ServerFactory加载即可.

?

static   ServerFactory mFactory;

static   void   Main( string [] args)

{

   

     mFactory = new   ServerFactory( "serverSection" );

     foreach   (IServer item in   mFactory.Servers)

     {

         Console.WriteLine( "{0} start @{1}" , item.Name, item.Port);

     }

     System.Threading.Thread.Sleep(-1);

}

 通过Beetle.Express可以非常方便就能构建TCP和UDP服务,而在购建的过程是完全不需要关心Socket相关细节,对于连接的处理和数据收发的细节对使用者来说都是完全透明的.组件还提供了基于LRU算法的连接清除对象,可以更方便地控制连接资源.

下载Sample

下载Beetle.Express和文档

可靠、高性能的Socket TCP通讯组件
开源数据库访问组件
c#组件设计交流群:47164588 
c# socket :136485198  微博http://weibo.com/ikende

 

分类:  Beetle

ActiveMQ-超越昨天的自己系列(1)

ActiveMQ(1)

扯个淡:  

  自己想个系列然后坚持下去,其实是个很不错的自我督促的学习方法。

   《我们到底能走多远系列》 已经挤出了25篇啦。在弄一个系列玩玩,主要用于提醒自己不断的学习新东西,可能都是入门级别的,只是为了拒绝停滞,或退步,为了让今天的自己比昨天的自己棒。

   不要和别人比,和昨天的自己比就可以了。

最近读《ActiveMQ in action》,整理学习后,记录下来。

附上自己的想法和问题,希望一起交流。

直接使用ActiveMQ:helloWord!

包结构:(注意对log4j和sl4f包的依赖问题)

Receive:

 package   d.c.home.test;

  import   javax.jms.Connection;
  import   javax.jms.ConnectionFactory;
  import   javax.jms.Destination;
  import   javax.jms.MessageConsumer;
  import   javax.jms.Session;
  import   javax.jms.TextMessage;
  import   org.apache.activemq.ActiveMQConnection;
  import   org.apache.activemq.ActiveMQConnectionFactory;

  public   class   Receiver {
      public   static   void   main(String[] args) {
          //   ConnectionFactory :连接工厂,JMS 用它创建连接 
         ConnectionFactory connectionFactory;
          //   Connection :JMS 客户端到JMS Provider 的连接 
        Connection connection =  null  ;
          //   Session: 一个发送或接收消息的线程 
         Session session;
          //   Destination :消息的目的地;消息发送给谁. 
         Destination destination;
          //   消费者,消息接收者 
         MessageConsumer consumer;
        connectionFactory  =  new   ActiveMQConnectionFactory(
                ActiveMQConnection.DEFAULT_USER,
                ActiveMQConnection.DEFAULT_PASSWORD,
                 "tcp://localhost:61616" );
          try   {
              //   构造从工厂得到连接对象 
            connection =  connectionFactory.createConnection();
              //   启动 
             connection.start();
              //   获取操作连接 
            session =  connection.createSession(Boolean.FALSE,
                    Session.AUTO_ACKNOWLEDGE);
              //   获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置 
            destination = session.createQueue("FirstQueue" );
            consumer  =  session.createConsumer(destination);
              while  ( true  ) {
                  //  设置接收者接收消息的时间,为了便于测试,这里谁定为100s 
                TextMessage message = (TextMessage) consumer.receive(100000 );
                  if  ( null  !=  message) {
                    System.out.println( "收到消息" +  message.getText());
                }   else   {
                      break  ;
                }
            }
        }   catch   (Exception e) {
            e.printStackTrace();
        }   finally   {
              try   {
                  if  ( null  !=  connection)
                    connection.close();
            }   catch   (Throwable ignore) {
            }
        }
    }
} 

Sender:

 package   d.c.home.test;

  import   javax.jms.Connection;
  import   javax.jms.ConnectionFactory;
  import   javax.jms.DeliveryMode;
  import   javax.jms.Destination;
  import   javax.jms.MessageProducer;
  import   javax.jms.Session;
  import   javax.jms.TextMessage;
  import   org.apache.activemq.ActiveMQConnection;
  import   org.apache.activemq.ActiveMQConnectionFactory;

  public   class   Sender {
      private   static   final   int  SEND_NUMBER = 5 ;

      public   static   void   main(String[] args) {
          //   ConnectionFactory :连接工厂,JMS 用它创建连接 
         ConnectionFactory connectionFactory;
          //   Connection :JMS 客户端到JMS Provider 的连接 
        Connection connection =  null  ;
          //   Session: 一个发送或接收消息的线程 
         Session session;
          //   Destination :消息的目的地;消息发送给谁. 
         Destination destination;
          //   MessageProducer:消息发送者 
         MessageProducer producer;
          //   TextMessage message;
          //   构造ConnectionFactory实例对象,此处采用ActiveMq的实现jar 
        connectionFactory =  new   ActiveMQConnectionFactory(
                ActiveMQConnection.DEFAULT_USER,
                ActiveMQConnection.DEFAULT_PASSWORD,
                 "tcp://localhost:61616" );
          try   {
              //   构造从工厂得到连接对象 
            connection =  connectionFactory.createConnection();
              //   启动 
             connection.start();
              //   获取操作连接 
            session =  connection.createSession(Boolean.TRUE,
                    Session.AUTO_ACKNOWLEDGE);
              //   获取session注意参数值FirstQueue是一个服务器的queue,须在在ActiveMq的console配置 
            destination = session.createQueue("FirstQueue" );
              //   得到消息生成者【发送者】 
            producer =  session.createProducer(destination);
              //   设置不持久化,此处学习,实际根据项目决定 
             producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
              //   构造消息,此处写死,项目就是参数,或者方法获取 
             sendMessage(session, producer);
            session.commit();
        }   catch   (Exception e) {
            e.printStackTrace();
        }   finally   {
              try   {
                  if  ( null  !=  connection)
                    connection.close();
            }   catch   (Throwable ignore) {
            }
        }
    }

      public   static   void   sendMessage(Session session, MessageProducer producer)
              throws   Exception {
          for  ( int  i = 1; i <= SEND_NUMBER; i++ ) {
            TextMessage message  =  session
                    .createTextMessage( "ActiveMq 发送的消息" +  i);
              //   发送消息到目的地方 
            System.out.println("发送消息:" + "ActiveMq 发送的消息" +  i);
            producer.send(message);
        }
    }
} 

启动两个main 就可以实现 hello world啦!

1,了解下ActiveMQ是做什么的?

没用前:

有了ActiveMQ后:

  

好吧,很容易理解,图片果然来得不叫快。

2,什么情况下可以用呢?

- 鉴于ActiveMQ支持多语言,除了支持java外还支持C/C++, .NET, Perl, PHP, Python, Ruby,所以,哈哈,多语言平台的交互!

- 远程方法调用, RMI ,很强大,但是如果你不想用,ActiveMQ会是一个可选的替代品!

- 解耦,对于一个越来越庞大,复杂的产品来说,是必经之路。一般,把一个个模块分出去,弄成应用级别,然后通过异步交互的方式实现解耦,ActiveMQ可以帮你实现

- 异步处理,web应用的同步执行高并发达到极限,只有通过异步的方式,来使性能再上台阶。

- 共用模块的实现,比如发邮件,发短信,log持久化,等这些功能呢个可能在多个应用中都有使用,只要写一个处理器,专门接受远程的message,然后实现功能。多个应用在开发这些功能时只要组装出一个message,扔给它就可以了。

3,关于message-oriented middleware(MOM) 面向对象的中间件 和 JMS


面向对象的中间件,是为了解决应用之间通过message形式交互提供的解决方案。这种中间件有很多,比如:WebSphere MQ,jboss的hornetQ

而 ActiveMQ就也这些中间件中的一员。

JMS  为这种中间提供商提供了统一的API接口,来定义一个消息的发送和接受的规范。

所有中间商可以实现这些接口以达到自己提供的jms服务,如此统一,有利于减少同提供商之间交互出现的不兼容。

JMS的作用:

JMS规定了什么东西? 既然中间件都直线了这些接口,我想只要熟悉了JMS规范,也差不多熟悉了所有的中间件了吧。

 1-message producers
使用MessageProducer,向目标发送message,也可以通过MessageProducer来设置一些信息

MessageProducer :

 public   interface   MessageProducer {
  void  setDisableMessageID( boolean  value)  throws   JMSException;
  boolean  getDisableMessageID()  throws   JMSException;
  void  setDisableMessageTimestamp( boolean  value)  throws   JMSException;
  boolean  getDisableMessageTimestamp()  throws   JMSException;
  void  setDeliveryMode( int  deliveryMode)  throws   JMSException;
  int  getDeliveryMode()  throws   JMSException;
  void  setPriority( int  defaultPriority)  throws   JMSException;
  int  getPriority()  throws   JMSException;
  void  setTimeToLive( long  timeToLive)  throws   JMSException;
  long  getTimeToLive()  throws   JMSException;
Destination getDestination()   throws   JMSException;
  void  close()  throws   JMSException;
  void  send(Message message)  throws   JMSException;
  void  send(Message message,  int  deliveryMode,  int   priority,
  long   timeToLive)
  throws   JMSException;
  void   send(Destination destination, Message message)
  throws   JMSException;
  void   send(
Destination destination,
Message message,
  int   deliveryMode,
  int   priority,
  long   timeToLive)
  throws   JMSException;
} 

2- MessageConsumer用来消费消息,

 public   interface   MessageConsumer {
String getMessageSelector()   throws   JMSException;
MessageListener getMessageListener()   throws   JMSException;
  void  setMessageListener(MessageListener listener)  throws   JMSException;
Message receive()   throws   JMSException;
Message receive(  long  timeout)  throws   JMSException;
Message receiveNoWait()   throws   JMSException;
  void  close()  throws   JMSException;
} 

3- Message  传递的内容信息对象

Message有head和body组成,head可以通过属性的设置来改变Message的一些特性:

 body的话,是通过键值对的方式来设置的,Message接口定义了不同数据类型的设置和取得的方法:

 public   interface   Message {
  boolean  getBooleanProperty(String name)  throws   JMSException;
  byte  getByteProperty(String name)  throws   JMSException;
  short  getShortProperty(String name)  throws   JMSException;
  int  getIntProperty(String name)  throws   JMSException;
  long  getLongProperty(String name)  throws   JMSException;
  float  getFloatProperty(String name)  throws   JMSException;
  double  getDoubleProperty(String name)  throws   JMSException;
String getStringProperty(String name)   throws   JMSException;
Object getObjectProperty(String name)   throws   JMSException;
Enumeration getPropertyNames()   throws   JMSException;
  boolean  propertyExists(String name)  throws   JMSException;
  void  setBooleanProperty(String name,  boolean  value)  throws   JMSException;
  void  setByteProperty(String name,  byte  value)  throws   JMSException;
  void  setShortProperty(String name,  short  value)  throws   JMSException;
  void  setIntProperty(String name,  int  value)  throws   JMSException;
  void  setLongProperty(String name,  long  value)  throws   JMSException;
  void  setFloatProperty(String name,  float  value)  throws   JMSException;
  void  setDoubleProperty(String name,  double  value)  throws   JMSException;
  void  setStringProperty(String name, String value)  throws   JMSException;
  void  setObjectProperty(String name, Object value)  throws   JMSException;
 } 

而Message下分为不同形式:

 

 

分类:  Java ,  笔记

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于使用Beetle.Express简单构建高吞吐的TCP&UDP应用的详细内容...

  阅读:50次