一般方法
让我们描述一种解决问题的方法。
在服务器端接收数据时,使用通道的远程地址(即
java.net.SocketAddress Channel.remoteAddress()
method
)识别客户。
Map<SocketAddress, Client>
,其中
Client
类或接口应包含相应的客户端连接(通道)关联上下文,包括其
Channel
. 确保地图保持最新:适当处理«client connected»和«client disconnected»事件。
识别客户端后,您可以使用客户端连接(通道)映射将适当的消息发送到客户端(当前发送客户端除外)。
此外,我想推荐您使用Netty找到一个很好的聊天应用程序实现,并看看它。
Netty特定解决方案
让我们考虑服务器端实现,特别是
ProcessingHandler
班
它已经通过将活动通道表示为通道组来管理它们:
static final ChannelGroup channels1 =
new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
当前实现处理通道变为活动事件,以使通道组保持最新:
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
channels1.add(ctx.channel());
// ...
}
但这仅仅是一半:还需要对称地处理通道变为非活动事件。实现应该如下所示:
@Override
public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
channels1.remove(ctx.channel());
}
广播:将接收到的消息发送到除当前频道外的所有频道
要实现所需的行为,只需通过引入适当的检查来更新实现,如下所示:
@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.
// ...
}
// ...
}
发送和接收字符串问题
Currently
,围绕
ResponseData
类不存在(未实现)。
以下内容
草稿
需要进行更改才能使客户端和服务器都工作。
-
这个
响应数据
类别:the
getStringValue
和
toString
应纠正方法:
String getStringValue() {
return this.strValue;
}
@Override
public String toString() {
return intValue + ";" + strValue;
}
-
这个
ResponseDataEncoder
类:它应该使用字符串值:
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);
}
-
这个
ResponseDataDecoder
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);
}
-
这个
ClientHandler
类:它应该正确接收和处理消息:
@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());
}
其他参考文献
-
«SecureChat â an TLS-based chat server, derived from the Telnet example», Netty Documentation
SecureChatServerHandler
class
.
-
«Netty in Action», Norman Maurer, Marvin Allen Wolfthal (ISBN-13: 978-1617291470)
,第3部分网络协议,12.2我们的示例WebSocket应用程序子章。介绍了基于浏览器的聊天应用程序的实现。