在上一篇文章中《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的消息推送方案之對象的傳遞(四)》