目录
server
引入jar包:
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.32.Final</version>
</dependency>
server start 代码:
package com.supermap.websocket.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import java.net.InetSocketAddress;
@Component
public class NettyServer {
// logger
private static final Logger logger = Logger.getLogger(NettyServer.class);
public void start(InetSocketAddress address) {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap().group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class).localAddress(address)
.childHandler(new ServerChannelInitializer()).option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
// 绑定端口,开始接收进来的连接
ChannelFuture future = bootstrap.bind(address).sync();
logger.info("Server start listen at " + address.getPort());
future.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
server 配置信息:
package com.supermap.websocket.server;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.net.InetSocketAddress;
@SpringBootApplication
public class AppApplication implements CommandLineRunner {
@Value("${netty.port}")
private int port;
@Value("${netty.url}")
private String url;
@Autowired
private NettyServer server;
public static void main(String[] args) {
SpringApplication.run(AppApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
InetSocketAddress address = new InetSocketAddress(url, port);
System.out.println("run .... . ... " + url);
server.start(address);
}
}
server 初始化信息:
package com.supermap.websocket.server;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;
public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel channel) throws Exception {
channel.pipeline().addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
channel.pipeline().addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
channel.pipeline().addLast(new ServerHandler());
}
}
server 消息处理:
package com.supermap.websocket.server;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class ServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) {
System.out.println("channelActive----->");
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("server channelRead......");
System.out.println(ctx.channel().remoteAddress() + "----->Server :" + msg.toString());
if(msg.toString().equals("001")) {
// 将客户端的信息直接返回写入ctx
ctx.write("server001");
ctx.flush();// 刷新缓存区
}else {
// 将客户端的信息直接返回写入ctx
ctx.writeAndFlush("999");
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
client start code:
package com.supermap.websocket.client;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
public class ClientWebSocket {
static final String HOST = System.getProperty("host", "127.0.0.1");
static final int PORT = Integer.parseInt(System.getProperty("port", "7000"));
static final int SIZE = Integer.parseInt(System.getProperty("size", "256"));
public static void main(String[] args) throws Exception {
sendMessage();
}
public static void sendMessage() throws InterruptedException {
// Configure the client.
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
p.addLast("decoder", new StringDecoder());
p.addLast("encoder", new StringEncoder());
p.addLast(new ClientHandler());
}
});
ChannelFuture future = b.connect(HOST, PORT).sync();
future.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
}
}
client链接初始化:
package com.supermap.websocket.client;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;
public class ClientChannelInitializer extends ChannelInitializer<SocketChannel> {
protected void initChannel(SocketChannel channel) throws Exception {
ChannelPipeline p = channel.pipeline();
p.addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
p.addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
p.addLast(new ClientHandler());
}
}
client 消息处理:
package com.supermap.websocket.client;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
public class ClientHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) {
System.out.println("ClientHandler Active");
ctx.writeAndFlush(Unpooled.copiedBuffer("001", CharsetUtil.UTF_8));
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
System.out.println("ClientHandler read Message:" + msg);
if(msg.toString().equals("server001")) {
//发送消息
ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks! 很奈斯", CharsetUtil.UTF_8));
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
server log:
run .... . ... 127.0.0.1
2019-05-05 18:25:19.927 INFO com.supermap.websocket.server.NettyServer - Server start listen at 7000
channelActive----->
server channelRead......
/127.0.0.1:11931----->Server :001
server channelRead......
/127.0.0.1:11931----->Server :Netty rocks! 很奈斯
client log:
ClientHandler read Message:server001
ClientHandler read Message:999
ok
在这里分享下 游戏开发和及时通讯的个人写法建议
server
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if(msg.toString().equals("001")) {//传来的如果是001就停止
ctx.writeAndFlush("over");
}else{
//即时通讯实现 去读取 缓存服务层,查看是否有和自己有关联的服务信息,如果有就通过这里返回用户
//游戏写法,可以写一个private 变量和一个public 变量,如果public更新就更新private和发送消息
// System.out.print("input send client info:");
// String read = new Scanner(System.in).nextLine();
// if (read.equals("quit")) {//获取到不同的信息做不同的任务
// //这里结束
// }else {
// ctx.writeAndFlush(Unpooled.copiedBuffer(read, CharsetUtil.UTF_8));
// }
ctx.writeAndFlush("ready");//发送ready 让客户端知道消息接受成功
}
System.out.println(ctx.channel().remoteAddress() + "----->Server :" + msg.toString());
}
client
public void channelRead(ChannelHandlerContext ctx, Object msg) {
System.out.println("server Message:" + msg);
if (msg.toString().equals("ready")) {
//即时通讯实现 更据服务端发来的信息做不同的任务
//游戏写法,可以写一个private 变量和一个public 变量,如果public更新就更新private和发送消息
System.out.print("input send client info:");
String read = new Scanner(System.in).nextLine();
if (read.equals("quit")) {
//这里结束
}else {
ctx.writeAndFlush(Unpooled.copiedBuffer(read, CharsetUtil.UTF_8));
}
} else if (msg.toString().equals("over")) {
}
}
有更好的建议多多提点
ok
文章持续更新