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

人生就是不断的转圈子——一个最简单的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 的一个群聊demo

    JBOSS Netty面试题

    JBOSS Netty面试题

    jboss netty5.0

    netty5.0源码包 + 需要的所有jar包 + 例子 解压导入eclipse即可运行

    Jprofile资料——使用JConsole实现JBoss性能监控

    Jprofile资料——使用JConsole实现JBoss性能监控Jprofile资料——使用JConsole实现JBoss性能监控Jprofile资料——使用JConsole实现JBoss性能监控

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

    NULL 博文链接:https://jonenine.iteye.com/blog/2170673

    netty-netty-3.10.6.Final.tar.gz

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

    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-demo实例

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

    Netty最新版下载

    可以用作一种高速的进行协议转换开发框架。Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。

    netty电子书

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

    经典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...

    netty4官方包

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

    saturnine:基于JBoss Netty的Clojure异步服务器应用程序框架

    它建立在JBoss Netty的基础上,并继承了该框架的许多功能,但在设计时考虑了简单性: Sane默认优先于显式配置。 内置的常用功能,包括字节,字符串(简单,tagsoup样式)流XML,JSON,HTTP,XMPP和Clojure表单的...

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

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

    Jboss开发J2EE程序例

    利用Jboss开发J2EE程序 一些例子

    Netty 3.1 中文用户手册

    JBoss Netty 3.1 中文用户手册

    netty-4.1-API.rar

    Netty 4.1 英文API——Netty是由JBOSS提供的一个java开源框架,现为 Github上的独立项目。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。

    netty-demo

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

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

    Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。

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

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

Global site tag (gtag.js) - Google Analytics