When receiving data on the server side, use the remote address of the channel (the java.net.SocketAddress Channel.remoteAddress() method) to identify the client.
Such identification may be done using a map like: Map<SocketAddress, Client>, where the Client class or interface should contain the appropriate client connection (channel) associated context, including its Channel. Be sure to keep the map up-to-date: handle the «client connected» and «client disconnected» events appropriately.
After a client is identified, you may just send the appropriate messages to the clients, except the current sending client, using the client connection (channel) map.
Additionally, I would like to recommend you to find a good implementation of a chat application using Netty and to take a look at it.
Netty-specific solution
Let's consider the server side implementation, in particular, the implementation of the ProcessingHandler class.
It already manages the active channels by representing them as the channel group:
static final ChannelGroup channels1 =
new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
Keeping the channel group up-to-date
The current implementation handles the «channel becomes active» event to keep the channel group up-to-date:
Broadcasting: Sending the received message to all channels, except the current one
To implement the desired behaviour, just update the implementation by introducing the appropriate check as follows:
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// ...
for (Channel ch : channels1) {
// Does `ch` represent the channel of the current sending client?
if (ch.equals(ctx.channel())) {
// Skip.
continue;
}
// Send the message to the `ch` channel.
// ...
}
// ...
}
Sending and receiving string problem
Currently, the functionality around the ResponseData class is not present (not implemented).
The following draft changes are required to make both the client and the server work.
The ResponseData class: the getStringValue and toString methods should be corrected:
The ResponseDataEncoder class: it should use the string value:
private final Charset charset = Charset.forName("UTF-8");
@Override
protected void encode(final ChannelHandlerContext ctx, final ResponseData msg, final ByteBuf out) throws Exception {
out.writeInt(msg.getIntValue());
out.writeInt(msg.getStringValue().length());
out.writeCharSequence(msg.getStringValue(), charset);
}
The ResponseDataDecoder class: it should use the string value:
private final Charset charset = Charset.forName("UTF-8");
@Override
protected void decode(final ChannelHandlerContext ctx, final ByteBuf in, final List<Object> out) throws Exception {
ResponseData data = new ResponseData();
data.setIntValue(in.readInt());
int strLen = in.readInt();
data.setStringValue(in.readCharSequence(strLen, charset).toString());
out.add(data);
}
The ClientHandler class: it should correctly receive and handle the message:
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
final ResponseData responseData = (ResponseData) msg;
System.out.println("The message sent from the server " + responseData);
update.accept(responseData.getIntValue());
}
Additional references
«SecureChat ‐ an TLS-based chat server, derived from the Telnet example», Netty Documentation. In particular, the implementation of the SecureChatServerHandler class.
General approach
Let's describe an approach to the problem.
When receiving data on the server side, use the remote address of the channel (the
java.net.SocketAddress Channel.remoteAddress()
method) to identify the client.Such identification may be done using a map like:
Map<SocketAddress, Client>
, where theClient
class or interface should contain the appropriate client connection (channel) associated context, including itsChannel
. Be sure to keep the map up-to-date: handle the «client connected» and «client disconnected» events appropriately.After a client is identified, you may just send the appropriate messages to the clients, except the current sending client, using the client connection (channel) map.
Additionally, I would like to recommend you to find a good implementation of a chat application using Netty and to take a look at it.
Netty-specific solution
Let's consider the server side implementation, in particular, the implementation of the
ProcessingHandler
class.It already manages the active channels by representing them as the channel group:
Keeping the channel group up-to-date
The current implementation handles the «channel becomes active» event to keep the channel group up-to-date:
But this is only a half: it is necessary to handle the «channel becomes inactive» event symmetrically as well. The implementation should look like:
Broadcasting: Sending the received message to all channels, except the current one
To implement the desired behaviour, just update the implementation by introducing the appropriate check as follows:
Sending and receiving string problem
Currently, the functionality around the
ResponseData
class is not present (not implemented).The following draft changes are required to make both the client and the server work.
The
ResponseData
class: thegetStringValue
andtoString
methods should be corrected:The
ResponseDataEncoder
class: it should use the string value:The
ResponseDataDecoder
class: it should use the string value:The
ClientHandler
class: it should correctly receive and handle the message:Additional references
SecureChatServerHandler
class.