Netty server and javafx services

Hi my server seems to stop without me telling it to 😦 The object of the Server class isn't getting garbage collected but it's channel does get magically stopped
5 Replies
JavaBot
JavaBot•2w ago
⌛ This post has been reserved for your question.
Hey @Noah | Nowipi! Please use /close or the Close Post button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically marked as dormant after 300 minutes of inactivity.
TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.
Noah | Nowipi
Noah | NowipiOP•2w ago
public class Server {

private static final StringDecoder DECODER = new StringDecoder();
private static final ChatMessageEncoder ENCODER = new ChatMessageEncoder();

private boolean running;
private EventLoopGroup bossGroup;
private EventLoopGroup workerGroup;
private Channel channel;

public Server() {}

public void start(int port) throws InterruptedException {
if (running)
throw new IllegalStateException("Server is already running");

running = true;
bossGroup = new NioEventLoopGroup(1);
workerGroup = new NioEventLoopGroup();
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(
DECODER,
ENCODER,
new ServerHandler()
);
}
});
channel = b.bind(port).sync().channel();

channel.closeFuture().addListener(_ -> {
System.out.println("Server is shutting down...");
stop(); // Gracefully stop the server when channel is closed
});
}

public void stop() {
if (running) {
channel.close().awaitUninterruptibly();
bossGroup.shutdownGracefully().awaitUninterruptibly();
workerGroup.shutdownGracefully().awaitUninterruptibly();

} else {
throw new IllegalStateException("Server isn't running");
}
}



public Channel getChannel() {
return channel;
}
}
public class Server {

private static final StringDecoder DECODER = new StringDecoder();
private static final ChatMessageEncoder ENCODER = new ChatMessageEncoder();

private boolean running;
private EventLoopGroup bossGroup;
private EventLoopGroup workerGroup;
private Channel channel;

public Server() {}

public void start(int port) throws InterruptedException {
if (running)
throw new IllegalStateException("Server is already running");

running = true;
bossGroup = new NioEventLoopGroup(1);
workerGroup = new NioEventLoopGroup();
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(
DECODER,
ENCODER,
new ServerHandler()
);
}
});
channel = b.bind(port).sync().channel();

channel.closeFuture().addListener(_ -> {
System.out.println("Server is shutting down...");
stop(); // Gracefully stop the server when channel is closed
});
}

public void stop() {
if (running) {
channel.close().awaitUninterruptibly();
bossGroup.shutdownGracefully().awaitUninterruptibly();
workerGroup.shutdownGracefully().awaitUninterruptibly();

} else {
throw new IllegalStateException("Server isn't running");
}
}



public Channel getChannel() {
return channel;
}
}
public class ServerService extends Service<Server> {

private final int port;

public ServerService(int port) {
this.port = port;
}

@Override
protected Task<Server> createTask() {
return new Task<>() {
@Override
protected Server call() throws Exception {
Server server = new Server();
updateMessage("Starting server...");
server.start(port);
updateMessage("Server started on port " + port);
return server;
}
};
}
}
public class ServerService extends Service<Server> {

private final int port;

public ServerService(int port) {
this.port = port;
}

@Override
protected Task<Server> createTask() {
return new Task<>() {
@Override
protected Server call() throws Exception {
Server server = new Server();
updateMessage("Starting server...");
server.start(port);
updateMessage("Server started on port " + port);
return server;
}
};
}
}
public class ServerHandler extends SimpleChannelInboundHandler<String> {

private final Map<Channel, User> connectedUsers = new HashMap<>();

@Override
public void channelInactive(ChannelHandlerContext ctx) {
System.err.println("Connection closed " + ctx.channel().isOpen());
}

@Override
public void handlerAdded(ChannelHandlerContext ctx) {
connectedUsers.put(
ctx.channel(),
null
);
}

@Override
public void handlerRemoved(ChannelHandlerContext ctx) {
User user = connectedUsers.remove(ctx.channel());
if (user != null) {
broadcast(new LeaveMessage(user));
}
}

@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) {
User sender = connectedUsers.get(ctx.channel());
if (sender == null) {
String username = msg.trim();
User user = new User(String.valueOf(connectedUsers.size()), username);
connectedUsers.put(ctx.channel(), user);
broadcast(new JoinMessage(user));
return;
}

broadcast(new UserMessage(msg, sender, LocalDateTime.now()));

}

private void broadcast(ChatMessage message) {
for (Channel client : connectedUsers.keySet()) {
if (client.isActive() && client.isWritable()) {
client.writeAndFlush(message);
}
}
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}

}
public class ServerHandler extends SimpleChannelInboundHandler<String> {

private final Map<Channel, User> connectedUsers = new HashMap<>();

@Override
public void channelInactive(ChannelHandlerContext ctx) {
System.err.println("Connection closed " + ctx.channel().isOpen());
}

@Override
public void handlerAdded(ChannelHandlerContext ctx) {
connectedUsers.put(
ctx.channel(),
null
);
}

@Override
public void handlerRemoved(ChannelHandlerContext ctx) {
User user = connectedUsers.remove(ctx.channel());
if (user != null) {
broadcast(new LeaveMessage(user));
}
}

@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) {
User sender = connectedUsers.get(ctx.channel());
if (sender == null) {
String username = msg.trim();
User user = new User(String.valueOf(connectedUsers.size()), username);
connectedUsers.put(ctx.channel(), user);
broadcast(new JoinMessage(user));
return;
}

broadcast(new UserMessage(msg, sender, LocalDateTime.now()));

}

private void broadcast(ChatMessage message) {
for (Channel client : connectedUsers.keySet()) {
if (client.isActive() && client.isWritable()) {
client.writeAndFlush(message);
}
}
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}

}
so the channelInactive gets called but I never use the stop method of my Server class
dan1st
dan1st•2w ago
Are you getting an exception? How do you see it being stopped? Maybe a client just disconnects? is handlerRemoved() called?
Noah | Nowipi
Noah | NowipiOP•2w ago
No exception handlerRemoved is getting called I'll investigate further fixed it was the client 🫣
JavaBot
JavaBot•2w ago
Post Closed
This post has been closed by <@270107388244262912>.
Want results from more Discord servers?
Add your server