Jump to content

[1.10.2][1.11.2] Server side message handling


OreCruncher

Recommended Posts

Server side I receive a message from a client.  While executing on the Netty thread I want to send that packet out to additional clients (essentially a star routing pattern).  Is it safe to handle all that on the Netty thread, or should I post a task to the Server thread and route from there?

Link to comment
Share on other sites

Follow on ....  how stable is sendToAllAround()?  I occasionally get the following exception when processing messages server side:

 

May 15, 2017 10:23:03 AM io.netty.channel.embedded.EmbeddedChannel recordException
WARNING: More than one exception was raised. Will report only the first one and log others.
java.lang.RuntimeException: DIMENSION expects an integer argument
	at net.minecraftforge.fml.common.network.FMLOutboundHandler$OutboundTarget$6.validateArgs(FMLOutboundHandler.java:171)
	at net.minecraftforge.fml.common.network.FMLOutboundHandler.write(FMLOutboundHandler.java:282)
	at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:658)
	at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:716)
	at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:651)
	at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:112)
	at io.netty.handler.codec.MessageToMessageCodec.write(MessageToMessageCodec.java:116)
	at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:658)
	at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:716)
	at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:706)
	at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:741)
	at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:895)
	at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:240)
	at net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper.sendToAllAround(SimpleNetworkWrapper.java:268)
	at org.blockartistry.DynSurround.network.Network.sendToAllAround(Network.java:128)
	at org.blockartistry.DynSurround.network.PacketPlaySound$PacketHandler.onMessage(PacketPlaySound.java:57)
	at org.blockartistry.DynSurround.network.PacketPlaySound$PacketHandler.onMessage(PacketPlaySound.java:1)
	at net.minecraftforge.fml.common.network.simpleimpl.SimpleChannelHandlerWrapper.channelRead0(SimpleChannelHandlerWrapper.java:56)
	at net.minecraftforge.fml.common.network.simpleimpl.SimpleChannelHandlerWrapper.channelRead0(SimpleChannelHandlerWrapper.java:36)
	at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)

 

The TargetPoint data used when doing the sendToAllAround() is embedded in the packet from the client.  Here is the packet handler:

 

	public static class PacketHandler implements IMessageHandler<PacketPlaySound, IMessage> {
		@Override
		@Nullable
		public IMessage onMessage(@Nonnull final PacketPlaySound message, @Nullable final MessageContext ctx) {
			if (ctx.side == Side.CLIENT) {
				// Don't forward if it the current player sent it
				final EntityPlayer player = EnvironState.getPlayer();
				if (player != null && message.locus.entityId != player.getEntityId())
					Network.postEvent(new PlayDistributedSoundEvent(message.soundClass, message.nbt));
			} else {
				// No event - turn around quick and broadcast to necessary
				// clients. This should take place on a Netty thread.
				Network.sendToAllAround(message.locus, message);
			}
			return null;
		}
	}

 

"locus" is a the TargetPoint in the incoming packet.  Network.sendToAllAround() is a simple wrapper:

 

	public static void sendToAllAround(@Nonnull final Locus point, @Nonnull final IMessage msg) {
		NETWORK.sendToAllAround(msg, point);
	}

 

And NETWORK is:

 

private static final SimpleNetworkWrapper NETWORK = NetworkRegistry.INSTANCE.newSimpleChannel(DSurround.MOD_ID);

 

So, how stable is it?  What is "DIMENSION expects an integer argument" telling me as a modder? 

 

EDIT:  Packet registrations in case it has bearing.  PacketPlaySound is registered both as a client-to-server message as well as server-to-client message:

 

	public static void initialize() {

		// Server -> Client messages
		NETWORK.registerMessage(PacketWeatherUpdate.PacketHandler.class, PacketWeatherUpdate.class, ++discriminator,
				Side.CLIENT);
		NETWORK.registerMessage(PacketHealthChange.PacketHandler.class, PacketHealthChange.class, ++discriminator,
				Side.CLIENT);
		NETWORK.registerMessage(PacketSpeechBubble.PacketHandler.class, PacketSpeechBubble.class, ++discriminator,
				Side.CLIENT);
		NETWORK.registerMessage(PacketEntityEmote.PacketHandler.class, PacketEntityEmote.class, ++discriminator,
				Side.CLIENT);
		NETWORK.registerMessage(PacketThunder.PacketHandler.class, PacketThunder.class, ++discriminator, Side.CLIENT);
		NETWORK.registerMessage(PacketEnvironment.PacketHandler.class, PacketEnvironment.class, ++discriminator,
				Side.CLIENT);
		NETWORK.registerMessage(PacketServerData.PacketHandler.class, PacketServerData.class, ++discriminator,
				Side.CLIENT);
		NETWORK.registerMessage(PacketDisplayFootprint.PacketHandler.class, PacketDisplayFootprint.class,
				++discriminator, Side.CLIENT);
		NETWORK.registerMessage(PacketPlaySound.PacketHandler.class, PacketPlaySound.class, ++discriminator,
				Side.CLIENT);

		// Client -> Server messages
		NETWORK.registerMessage(PacketDisplayFootprint.PacketHandler.class, PacketDisplayFootprint.class,
				++discriminator, Side.SERVER);
		NETWORK.registerMessage(PacketPlaySound.PacketHandler.class, PacketPlaySound.class, ++discriminator,
				Side.SERVER);
	}

 

 

Edited by OreCruncher
Link to comment
Share on other sites

OK - I have a theory.  What I think is happening is that the main server thread is trying to send the client a packet at the same time the server netty thread is doing routing.  One stomps on the other causing the channel to lose its mind.  I put in code to synchronize access to the channel and I haven't seen the issue reappear.  Keeping my fingers crossed.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.