1. 程式人生 > >Android 基於Netty的訊息推送方案之字串的接收和傳送(三)

Android 基於Netty的訊息推送方案之字串的接收和傳送(三)

在上一篇文章中Android 基於Netty的訊息推送方案之概念和工作原理(二) ,我們介紹過一些關於Netty的概念和工作原理的內容,今天我們先來介紹一個叫做ChannelBuffer的東東。

ChannelBuffer


 Netty中的訊息傳遞,都必須以位元組的形式,以ChannelBuffer為載體傳遞。簡單的說,就是你想直接寫個字串過去,對不起,拋異常。雖然,Netty定義的writer的介面引數是Object的,這可能也是會給新上手的朋友容易造成誤會的地方。Netty原始碼中,是這樣判斷的。

SendBuffer acquire(Object message) {
        if (message instanceof ChannelBuffer) {
            return acquire((ChannelBuffer) message);
        } else if (message instanceof FileRegion) {
            return acquire((FileRegion) message);
        }
 
        throw new IllegalArgumentException(
                "unsupported message type: " + message.getClass());
    }
接下來我們寫一個Demo來學習它。

服務端程式碼如下

public class MessageServer {
	public static void main(String args[]){
		//服務啟動器
		ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newCachedThreadPool(),Executors.newCachedThreadPool()));
		//設定一個處理客戶端訊息和各種訊息事件的類(Handler)
		bootstrap.setPipelineFactory(new ChannelPipelineFactory(){
			@Override
			public ChannelPipeline getPipeline() throws Exception {
				return Channels.pipeline(new BusinessHandler());
			}			
		});
		//開放8000埠供客戶端連線
		bootstrap.bind(new InetSocketAddress(8000));
	}
	
	private static class BusinessHandler extends SimpleChannelHandler{
		// 服務端收到客戶端傳送過來的訊息時,觸發此方法
		@Override
        public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
        	ChannelBuffer buffer = (ChannelBuffer)e.getMessage();
        	System.out.println("Receive:"+buffer.toString(Charset.defaultCharset()));
        	String msg = buffer.toString(Charset.defaultCharset()) + "has been processed!";
        	ChannelBuffer buffer2 = ChannelBuffers.buffer(msg.length());
        	buffer2.writeBytes(msg.getBytes());
        	e.getChannel().write(buffer2);
        }
	}
}
客戶端程式碼如下

public class MessageClient {
	public static void main(String args[]) {
		ClientBootstrap bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
		
		bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
			@Override
			public ChannelPipeline getPipeline() throws Exception {
				return Channels.pipeline(new MessageClientHandler());
			}
		});
		bootstrap.connect(new InetSocketAddress("127.0.0.1", 8000));
	}

	private static class MessageClientHandler extends SimpleChannelHandler {
		/**
		 * 當繫結到服務端的時候觸發,給服務端發訊息。
		 */
		@Override
		public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
			// 將字串,構造成ChannelBuffer,傳遞給服務端
			String msg = "Hello, I'm client.";
			ChannelBuffer buffer = ChannelBuffers.buffer(msg.length());
			buffer.writeBytes(msg.getBytes());
			e.getChannel().write(buffer);
		}
	}
}

先啟動服務端,再啟動客戶端,可以看到服務端列印如下字串

Receive:Hello, I'm client.

如果你感興趣,請繼續閱讀 《Android 基於Netty的訊息推送方案之物件的傳遞(四)》