我使用Netty使用聊天从服务器到客户端停留在广播消息
我已经可以从客户端与服务器聊天并从服务器进行自动重放(使用处理),现在我想要的是服务器可以像客户端一样聊天并将其广播到所有客户端(频道激活)。
我试图从我的客户端复制,但它没有用,
Channel channel = boostrap.bind(port).sync().channel();
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while(true) {
channel.writeAndFlush(in.readLine() + "\r\n");
}
很抱歉Android代码,因为稍后我想在Android上使用此代码客户端考虑到Nio不能在Android上运行,但是Oio可以工作。
我包含了我工作的所有代码,
//ChatServer.java
public class ChatServer {
private final int port;
public static void main(String[] args) throws Exception {
System.out.println("Server Started at " + InetAddress.getLocalHost().getHostAddress() + " port " + 9999);
new ChatServer(9999).run();
}
public ChatServer(int port) {
this.port = port;
}
public void run() throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap boostrap = new ServerBootstrap()
.group(bossGroup,workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChatServerInitializer());
Channel channel = boostrap.bind(port).sync().channel();
// channel.closeFuture().sync();
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while(true) {
channel.writeAndFlush(in.readLine() + "\r\n");
}
}finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
// ChatServerHandler.java
public class ChatServerhandler extends SimpleChannelInboundHandler<String> {
private static final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
Channel incoming = ctx.channel();
for (Channel channel: channels) {
channel.writeAndFlush("[SERVER] " + incoming.remoteAddress() + " has joined \n");
}
channels.add(ctx.channel());
}
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
Channel incoming = ctx.channel();
for (Channel channel: channels) {
channel.flush();
channel.writeAndFlush("[SERVER] " + incoming.remoteAddress() + " has left \n");
}
channels.remove(ctx.channel());
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
Channel incoming = ctx.channel();
System.out.println("[" + incoming.remoteAddress() + "] " + msg + "\n");
for (Channel channel: channels) {
if(channel != incoming) {
channel.writeAndFlush("[" + incoming.remoteAddress() + "] " + msg + "\n");
}
}
}
}
//ChatServerInitializer.java
public class ChatServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected 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 ChatServerhandler());
}
}
//ChatClient.java
public class ChatClient {
private final String host;
private final int port;
public static void main(String[] args) throws Exception {
System.out.println("Client Started, conntected to " + "192.168.0.61:9999");
new ChatClient("192.168.0.61", 9999).run();
}
public ChatClient(String host, int port) {
this.host = host;
this.port = port;
}
private void run() throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap()
.group(group)
.channel(NioSocketChannel.class)
.handler(new ChatClientInitializer());
Channel channel = bootstrap.connect(host, port).sync().channel();
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while(true) {
channel.writeAndFlush(in.readLine() + "\r\n");
}
}finally {
group.shutdownGracefully();
}
}
}
// ChatClientHandler.java
public class ChatClienthandler extends SimpleChannelInboundHandler<String>{
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println(msg);
}
}
// ChatClientInitializer.java
public class ChatClientInitializer extends ChannelInitializer<SocketChannel>{
@Override
protected 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 ChatClienthandler());
}
}
答案 0 :(得分:1)
好的,我发现我的情况,我必须创建新的线程,以使服务器可以像客户端聊天。在服务器关闭同步之前为服务器创建一个新线程,我使用ChatServerBroadcast。然后使用static将其直接调用到处理程序,以发送到所有活动的通道。
ChatServer.java/run
ChannelFuture f = boostrap.bind(PORT).sync();
ChatServerBroadcast cst = new ChatServerBroadcast();
f.channel().closeFuture().sync();
ChatServerBroadcast.java
public class ChatServerBroadcast implements Runnable{
private String message = "";
public ChatServerBroadcast() {
new Thread(this).start();
}
@Override
public void run() {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Ready to chat ");
while(true) {
try {
message = in.readLine();
} catch (IOException e) {
message = "";
}
if(!message.isEmpty()) {
message = "[SERVER BROADCAST] " + message + "\r\n";
ChatServerhandler.sendServerMessage(message);
message = "";
}
}
}
}
ChatServerHandler.java/sendServeMessage(字符串)
public static void sendServerMessage(String message) {
if (channels.isEmpty()) {
return;
}
channels.writeAndFlush(message);
}
也许它可以帮助某人在像我这样的情况下寻找答案。
答案 1 :(得分:0)
您应该将代码从handlerAdded移动到channelActive,从handlerRemoved移动到channelInactive。这应该是我认为的工作。