服务器端相关代码:
服务器自定义handle:
客户端相关代码:
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import java.net.InetSocketAddress;
public class Client {
private final int port;
private final String host;
public Client(int port, String host) {
this.port = port;
this.host = host;
}
public void start() throws InterruptedException {
/*线程组*/
EventLoopGroup group = new NioEventLoopGroup();
try{
/*客户端启动必备*/
Bootstrap b = new Bootstrap();
b.group(group)/*把线程组传入*/
/*指定使用NIO进行网络传输*/
.channel(NioSocketChannel.class)
.remoteAddress(new InetSocketAddress(host,port))
.handler(new ClientHandle());
/*连接到远程节点,阻塞直到连接完成*/
ChannelFuture f = b.connect().sync();
/*阻塞程序,直到Channel发生了关闭*/
f.channel().closeFuture().sync();
}finally {
group.shutdownGracefully().sync();
}
}
public static void main(String[] args) throws InterruptedException {
new Client(9999,"127.0.0.1").start();
}
}
业务逻辑处理代码:
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;
public class ClientHandle extends SimpleChannelInboundHandler<ByteBuf> {
/*客户端读到数据以后,就会执行*/
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg){
// 传统的HTTP接入
if (msg instanceof FullHttpRequest) {
handleHttpRequest(ctx, (FullHttpRequest) msg);
}
// WebSocket接入
else if (msg instanceof WebSocketFrame) {
handleWebSocketFrame(ctx, (WebSocketFrame) msg);
}
}
/*连接建立以后*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(Unpooled.copiedBuffer(
"Hello Netty",CharsetUtil.UTF_8));
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
cause.printStackTrace();
ctx.close();
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
super.userEventTriggered(ctx, evt);
}
private void handleWebSocketFrame(ChannelHandlerContext ctx,
WebSocketFrame frame) {
//判断是否式打开链路指令
// 判断是否是关闭链路的指令
if (frame instanceof CloseWebSocketFrame) {
handshaker.close(ctx.channel(),
(CloseWebSocketFrame) frame.retain());
return;
}
// 判断是否是Ping消息
if (frame instanceof PingWebSocketFrame) {
ctx.channel().write(
new PongWebSocketFrame(frame.content().retain()));
return;
}
// 本例程仅支持文本消息,不支持二进制消息
if (!(frame instanceof TextWebSocketFrame)) {
throw new UnsupportedOperationException(String.format(
"%s frame types not supported", frame.getClass().getName()));
}
// 返回应答消息
String _message = ((TextWebSocketFrame) frame).text();
JSONObject chat = JSON.parseObject(_message);
String type = chat.get("type").toString();
if ("login".equals(type)) {
handleWebSocketLogin(chat, ctx);
} else if ("logout".equals(type)) {
handleWebSocketLogout(chat);
} else if ("message".equals(type)) {
handleWebSocketMessage(_message);
}
}