Android作为客户端,采用Netty与服务器通信
参考:Netty 实现聊天功能 - waylau的个人页面 - 开源中国社区 http://my.oschina.net/waylau/blog/380957在此基础上制作Android版本服务器三个文件SubReqServer.javaSimpleChatServerInitializer.javaSimpleChatServerHandler.jav
参考:
Netty 实现聊天功能 - waylau的个人页面 - 开源中国社区 http://my.oschina.net/waylau/blog/380957
在此基础上制作Android版本
服务器三个文件
SubReqServer.java
SimpleChatServerInitializer.java
SimpleChatServerHandler.java
SubReqServer.java
package com.test.netty;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
public class SubReqServer {
public void run(int nPort) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try{
ServerBootstrap b = new ServerBootstrap(); // (2)
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class) // (3)
.childHandler(new SimpleChatServerInitializer()) //(4)
.option(ChannelOption.SO_BACKLOG, 128) // (5)
.childOption(ChannelOption.SO_KEEPALIVE, true); // (6)
System.out.println("服务器已启动,等待客户端连接");
// 绑定端口,开始接收进来的连接
ChannelFuture f = b.bind(nPort).sync(); // (7)
// 等待服务器 socket 关闭 。
// 在这个例子中,这不会发生,但你可以优雅地关闭你的服务器。
f.channel().closeFuture().sync();
}finally {
System.out.println("---------------Shut down");
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
public static void main(String[] args){
int nPort = 9999;
nPort = Integer.valueOf(nPort);
System.out.println("---------------Main start");
try {
new SubReqServer().run(nPort);
} catch (Exception e) {
System.out.println("---------------Main Error");
e.printStackTrace();
}
}
}
SimpleChatServerInitializer.java
package com.test.netty;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
public class SimpleChatServerInitializer extends
ChannelInitializer<SocketChannel> {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
pipeline.addLast("decoder", new StringDecoder());
pipeline.addLast("encoder", new StringEncoder());
pipeline.addLast("handler", new SimpleChatServerHandler());
System.out.println("SimpleChatClient:"+ch.remoteAddress() +"连接上");
}
}
SimpleChatServerHandler.java
package com.test.netty;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
public class SimpleChatServerHandler extends SimpleChannelInboundHandler<String> { // (1)
/**
* A thread-safe Set Using ChannelGroup, you can categorize Channels into a meaningful group.
* A closed Channel is automatically removed from the collection,
*/
public static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception { // (2)
Channel incoming = ctx.channel();
System.out.println("---------------handlerAdded");
// Broadcast a message to multiple Channels
channels.writeAndFlush("[SERVER] - " + incoming.remoteAddress() + " 加入\n");
channels.add(ctx.channel());
}
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { // (3)
Channel incoming = ctx.channel();
System.out.println("---------------handlerRemoved");
// Broadcast a message to multiple Channels
channels.writeAndFlush("[SERVER] - " + incoming.remoteAddress() + " 离开\n");
// A closed Channel is automatically removed from ChannelGroup,
// so there is no need to do "channels.remove(ctx.channel());"
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, String s) throws Exception { // (4)
System.out.println("---------------channelRead0 have received : " + s + " ");
Channel incoming = ctx.channel();
for (Channel channel : channels) {
if (channel != incoming){
channel.writeAndFlush("[" + incoming.remoteAddress() + "]" + "Hello " + "\n");
} else {
channel.writeAndFlush("[you]" + s + "\n");
}
}
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception { // (5)
Channel incoming = ctx.channel();
System.out.println("SimpleChatClient:---"+incoming.remoteAddress()+"---在线");
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception { // (6)
Channel incoming = ctx.channel();
System.out.println("SimpleChatClient:---"+incoming.remoteAddress()+"---掉线");
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
Channel incoming = ctx.channel();
System.out.println("SimpleChatClient:---"+incoming.remoteAddress()+"---异常");
// 当出现异常就关闭连接
cause.printStackTrace();
ctx.close();
}
}
客户端四个文件
MainActivity.java
TcpClient.java
SimpleChatClientInitializer.java
SimpleChatClientHandler.java
MainActivity.java
package com.example.videonetty;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
public class MainActivity extends Activity {
Button btnSend;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnSend = (Button)findViewById(R.id.btnSend);
//Netty 线程
TcpClient client = new TcpClient();
client.start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
TcpClient.java
package com.example.videonetty;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
public class TcpClient extends Thread {
public static String HOST = "168.168.1.121";
public static int PORT = 9999;
public void run() {
super.run();
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap()
.group(group)
.channel(NioSocketChannel.class)
.handler(new SimpleChatClientInitializer());
Channel channel = bootstrap.connect(HOST, PORT).sync().channel();
while(true){
channel.writeAndFlush("this msg test come from client" + "\r\n");
Thread.currentThread();
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
group.shutdownGracefully();
}
}
}
SimpleChatClientInitializer.java
package com.example.videonetty;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
public class SimpleChatClientInitializer extends ChannelInitializer<SocketChannel>{
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
pipeline.addLast("decoder", new StringDecoder());
pipeline.addLast("encoder", new StringEncoder());
pipeline.addLast("handler", new SimpleChatClientHandler());
}
}
SimpleChatClientHandler.java
package com.example.videonetty;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
public class SimpleChatClientHandler extends SimpleChannelInboundHandler<String> {
protected void channelRead0(ChannelHandlerContext ctx, String s) throws Exception {
System.out.println("---------------channelRead0 have received : " + s + " ");
}
}
效果:
服务器:
---------------Main start
服务器已启动,等待客户端连接
---------------handlerAdded
SimpleChatClient:/172.16.25.2:41291连接上
SimpleChatClient:---/172.16.25.2:41291---在线
---------------channelRead0 have received : this msg test come from client
---------------channelRead0 have received : this msg test come from client
---------------channelRead0 have received : this msg test come from client
---------------channelRead0 have received : this msg test come from client
---------------channelRead0 have received : this msg test come from client
客户端:
04-07 06:34:17.029: I/System.out(14664): ---------------channelRead0 have received : [you]this msg test come from client
........
源码下载: Eclipse + Netty 4.0.035
http://download.csdn.net/detail/yulinxx/9483752
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)