`
wenjixiao
  • 浏览: 194277 次
社区版块
存档分类
最新评论

人生就是不断的转圈子——一个最简单的jboss netty chat测试程序

    博客分类:
  • life
阅读更多
这几天,研究网络和分布式——我想弄一个可自由扩展的高效率的围棋系统。
有几个问题是要必须得解决的:
1,协议的设计,也就是通信
2,服务器端的架构,比如是阻塞还是事件io之类的支持,包括集群
3,基本网络架构的选择,java nio的框架,实在是有点复杂。

我参考了几个东西:
1,jboss netty一个很不错的基础框架,很干净,我很喜欢
2,apache mina和jboss netty有亲戚,不过我觉得有点乱
3,jcsp这个东西很好,让我对于通讯和计算有了更加深入一点的了解,很漂亮的模型(CSP)
4,java jini,以前我就看过jini实在是那时候,水平太低,没明白,现在大概清楚它是啥东西了——比较高层,sun真的比较超前
5,erlang,我一直犹豫,是不是该用erlang一个搞定所有的问题得了,但是,erlang把你限定的太死了,你没了选择,当然,它很好,直到现在,我还是一头雾水。

我用jboss netty做了一个聊天的程序(主要是测试一下netty的功能),我发现很简单,可是,对于协议的设计,我始终不够自信,我觉得肯定还有什么问题。我的现在的方法只是单向消息对象,只是发消息,收消息,处理消息,其他的一概不理。我觉得不够严谨,到底应该怎么做,我不知道。

现在把代码贴一下,做个纪念吧!
这个程序主要参照了jboss netty里的一个securechat的例子,我去掉了secure的功能,同时加上了swing界面。

package orange;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
/**
* swing 的client!
*/
public class OrangeClient {
	private JTextField input=new JTextField(20);
	private JTextField output=new JTextField(20);
	OrangeClientHandler handler;
	public OrangeClient(){
		String host="localhost";
		int port=8081;
		ChannelFactory factory=
			new NioClientSocketChannelFactory(
					Executors.newCachedThreadPool(),
					Executors.newCachedThreadPool());

		ClientBootstrap bootstrap=new ClientBootstrap(factory);
		handler=new OrangeClientHandler(output);

		bootstrap.setPipelineFactory(new OrangePipelineFactory(handler));
		bootstrap.setOption("tcpNoDelay", true);
		bootstrap.setOption("keepAlive", true);

		bootstrap.connect(new InetSocketAddress(host, port));
	}
	public void init(){
		JFrame frame=new JFrame("Orange Client!");
		Container container=frame.getContentPane();
		frame.addWindowListener(new WindowAdapter(){
			@Override
			public void windowClosing(WindowEvent e){
				System.exit(0);
			}
		});

		JPanel pInput=new JPanel();
		pInput.setLayout(new FlowLayout());
		JLabel inputLabel=new JLabel("input:");

		JButton inputButton=new JButton("To Server!");
		inputButton.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				Channel mych=handler.getMyChannel();
				if(mych.isOpen()){
					ChannelFuture f=mych.write(input.getText()+'\n');
					f.addListener(new ChannelFutureListener(){
						@Override
						public void operationComplete(ChannelFuture future)
						throws Exception {
							System.out.println("ok!");
						}

					});
				}
			}

		});
		pInput.add(inputLabel);
		pInput.add(input);
		pInput.add(inputButton);

		JPanel pOutput=new JPanel();
		pOutput.setLayout(new FlowLayout());
		JLabel outputLabel=new JLabel("output:");

		pOutput.add(outputLabel);
		pOutput.add(output);

		container.setLayout(new BorderLayout());
		container.add(BorderLayout.NORTH,pInput);
		container.add(BorderLayout.SOUTH,pOutput);
		frame.setLocation(400, 400);
		frame.pack();
		frame.setVisible(true);

	}
	public static void main(String[] args){
		OrangeClient client=new OrangeClient();
		client.init();
	}

}


package orange;

import javax.swing.JTextField;

import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipelineCoverage;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
/**
*  client handler
*/
@ChannelPipelineCoverage("one")
public class OrangeClientHandler extends SimpleChannelHandler {
	private Channel myChannel;
	private JTextField myout;
	public OrangeClientHandler(JTextField out){
		this.myout=out;
	}
	
	@Override
	public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
		setMyChannel(e.getChannel());
	}

	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
		String data=(String) e.getMessage();
		myout.setText(data);
	}
	
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
		e.getChannel().close();
	}

	public Channel getMyChannel() {
		return myChannel;
	}
	
	public void setMyChannel(Channel myChannel) {
		this.myChannel = myChannel;
	}
	
}

package orange;
import static org.jboss.netty.channel.Channels.pipeline;

import org.jboss.netty.channel.ChannelHandler;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.handler.codec.serialization.ObjectDecoder;
import org.jboss.netty.handler.codec.serialization.ObjectEncoder;
/**
*这个PipelineFactory很重要,它定义了用serialize object通讯 
*定义了编码和解码,以及client 和 server的handler的指定
*/
public class OrangePipelineFactory implements ChannelPipelineFactory {
	private ChannelHandler handler;
	public OrangePipelineFactory(ChannelHandler handler){
		this.handler=handler;
	}
	@Override
	public ChannelPipeline getPipeline(){
		ChannelPipeline pipeline = pipeline();
        pipeline.addLast("decoder", new ObjectDecoder());//up
        pipeline.addLast("encoder", new ObjectEncoder());//down	
        pipeline.addLast("myhandler", handler);//my handler include up and down
		return pipeline;
	} 

}

package orange;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
/**
* server
*/
public class OrangeServer {
	public static void main(String[] args) throws Exception{
		ChannelFactory factory=
			new NioServerSocketChannelFactory(
					Executors.newCachedThreadPool(),
					Executors.newCachedThreadPool());
		ServerBootstrap bootstrap=new ServerBootstrap(factory);
		OrangeServerHandler handler=new OrangeServerHandler();
		
		bootstrap.setPipelineFactory(new OrangePipelineFactory(handler));
		bootstrap.setOption("child.tcpNoDelay", true);
		bootstrap.setOption("child.keepAlive",true);
		
		bootstrap.bind(new InetSocketAddress(8081));
	}
}

package orange;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipelineCoverage;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
/**
*server side handler,它可以说是最主要的处理事情的地方,我现在只是把所有的channel
*放在集合里,有对象来的时候,就告诉大家
*/
@ChannelPipelineCoverage("all")
public class OrangeServerHandler extends SimpleChannelHandler {
    static final Set<Channel> channels =Collections.synchronizedSet(new HashSet<Channel>());
    
    @Override
	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
    	Channel ch=e.getChannel();
    	channels.remove(ch);
    	ch.close();
	}

	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
		
        // Convert to a String first.
        String request = (String) e.getMessage();
        // Send the received message to all channels but the current one.
        for (Channel c: channels) {
            if (c != e.getChannel()) {
                c.write("[" + e.getChannel().getRemoteAddress() + "] " +
                        request + '\n');
            }
        }

        // Close the connection if the client has sent 'bye'.
        if (request.toLowerCase().equals("bye")) {
            e.getChannel().close();
        }
	}

	@Override
	public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
		channels.add(e.getChannel());
	}
	
}



我知道我又回到了老地方,我在不断的绕着圈子,不过这个圈子是螺旋上升的。
每一次,我都会在稍微高一点的地方看原来的问题,这也许就是生命智力的有限和无奈啊!
如果我一开始就可以看穿这一切,那么,我不就可以省了很多的功夫了吗?!
分享到:
评论
3 楼 yuqilin001 2012-06-09  
// Close the connection if the client has sent 'bye'. 
        if (request.toLowerCase().equals("bye")) { 
            e.getChannel().close(); 
        } 


这里执行后,还能继续发消息,能解答下吗?谢谢
2 楼 fitliving 2010-08-28  
请问您如何让 netty 不用 ChannelBuffer这数据类型的改用string ,就是客户端用netty ,服务器用java socket如何解析请求数据接受数据,求您的见解
1 楼 love_seam 2009-08-06  
支持一下。

jgroups也可以。

相关推荐

    jboss netty chat

    JBoss Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。在本示例“jboss netty chat”中,我们关注的是如何利用Netty实现一个群聊功能,即WebChat。Netty因其...

    jboss netty5.0

    Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。这里我们关注的是 Netty 的第五个主要版本,即 Netty 5.0。尽管在撰写本文时,Netty 的最新稳定版本是 4.x ...

    JBOSS Netty面试题

    JBOSS Netty面试题 在这篇文章中,我们将探讨 JBOSS Netty 面试题,涵盖了 BIO、NIO 和 AIO 的区别、NIO 的组成、Netty 的特点等知识点。 BIO、NIO 和 AIO 的区别 BIO(Blocking I/O)是一种传统的 I/O 模式,每...

    使用jboss netty 创建高性能webservice客户端及服务端

    JBoss Netty是一个高性能、异步事件驱动的网络应用程序框架,它为快速开发可维护的高性能协议服务器和客户端提供了丰富的API。本篇文章将深入探讨如何利用JBoss Netty创建高效的Web Service客户端和服务端。 首先,...

    Netty (netty-3.2.5.Final.jar,netty-3.2.5.Final-sources.jar)

    Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。这个压缩包包含 `netty-3.2.5.Final.jar` 和 `netty-3.2.5.Final-sources.jar` 两个文件,它们分别代表了...

    netty-netty-3.10.6.Final.tar.gz

    Netty (netty-netty-3.10.6.Final.tar.gz)是一个 NIO 客户端服务器框架,可以快速轻松地开发协议服务器和客户端等网络应用程序。它极大地简化和流线了网络编程,例如 TCP 和 UDP 套接字服务器。 “快速和简单”并...

    jboss教程——快速上手指南

    【JBoss教程——快速上手指南】 JBoss,全称为Red Hat JBoss Middleware,是由Red Hat公司开发的一款开源中间件服务器,它基于Java EE(Java Platform, Enterprise Edition)标准,提供了一个全面的企业级应用...

    netty-3.9.9.Final-API文档-中文版.zip

    赠送jar包:netty-3.9.9.Final.jar; 赠送原API文档:netty-3.9.9.Final-javadoc.jar; 赠送源代码:netty-3.9.9.Final-sources.jar; 赠送Maven依赖信息文件:netty-3.9.9.Final.pom; 包含翻译后的API文档:netty-...

    netty socketio 在线聊天程序

    Netty是由JBOSS提供的一个高性能、异步事件驱动的网络应用框架,用于快速开发可维护的高性能协议服务器和客户端。它主要特点包括: 1. **异步IO模型**:Netty基于NIO(非阻塞I/O)模型,提供了一种高效的事件驱动的...

    resteasy使用netty

    RestEasy是JBoss公司开发的一个Java框架,它实现了JSR 311和JSR 339(Java API for RESTful Web Services)标准,用于简化RESTful服务的开发。而Netty则是一个异步事件驱动的网络应用框架,适用于高并发、低延迟的...

    netty-demo实例

    也就是说,Netty 是一个基于NIO的客户,服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty相当简化和流线化了网络应用的编程开发过程,例如,...

    netty-3.7.0官方API所有jar包

    Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。这个“netty-3.7.0官方API所有jar包”提供了Netty 3.7.0版本的完整API文档、所有相关的jar包以及示例代码,...

    Jboss开发J2EE程序例

    在J2EE应用程序开发中,JBoss是一款广泛使用的开源应用服务器,它提供了全面的Java企业级服务,包括Servlet、JSP、EJB、JMS、JPA、JSF等。本教程将深入探讨如何利用JBoss来开发和部署J2EE程序。 1. **JBoss环境搭建...

    netty in action 中文版 高清带目录 来个最便宜的

    Netty是一款由JBOSS提供支持的Java开源框架,用于快速开发高性能、高可靠性的网络服务器和客户端程序。它提供异步的、事件驱动的网络应用程序框架和工具,以支持复杂的网络操作。Netty是建立在Java NIO之上的,这...

    精通JBoss——EJB与Web Services开发精解

    《精通JBoss——EJB与Web Services开发精解》是一本深入探讨企业级Java应用开发的专业书籍,专注于JBoss应用服务器的使用以及EJB(Enterprise JavaBeans)和Web Services的集成开发。本书旨在帮助读者全面掌握如何在...

    Netty中文指南教程

    以下是一个简单的Netty服务器处理器实现示例,用于展示如何创建一个抛弃协议(即不处理任何接收到的数据)的服务器: ```java package org.jboss.netty.example.discard; import org.jboss.netty.channel.Channel;...

    经典JAVA EE企业应用实战基于WEBLOGIC JBOSS的JSF+EJB 3+JPA整合开发——源码.part1

    经典JAVA EE企业应用实战基于WEBLOGIC JBOSS的JSF+EJB 3+JPA整合开发——源码.part1 其他部分详见我的上传列表,全部分卷下载完成才能解压。 本书介绍了Java EE规范的三大主要规范JSF、EJB 3和JPA,其中JSF是Sun...

    jboss——suse安装手册

    而JBoss,作为一款开源的应用服务器,广泛应用于Java EE应用的部署。本篇将详细介绍如何在SUSE Linux上安装和配置JBoss。 首先,安装JDK是部署JBoss的前提。JDK(Java Development Kit)提供了开发和运行Java应用...

    netty4官方包

    也就是说,Netty 是一个基于NIO的客户,服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty相当简化和流线化了网络应用的编程开发过程,例如,...

    快速配置Jboss开发与测试环境-初学者快速指导

    以下内容将围绕如何在JBoss中快速部署一个Web应用的开发或测试环境展开,特别关注于JBoss 4.0.2版本的配置过程。 #### 二、快速部署Web应用 **步骤1:部署Web应用** - **目录结构**:确保应用遵循Web应用规范的...

Global site tag (gtag.js) - Google Analytics