From 9a9365c2a5e5a994c2731d9cbc5091bf81da2e52 Mon Sep 17 00:00:00 2001 From: MobiusDev <8391001+MobiusDevelopment@users.noreply.github.com> Date: Fri, 4 Dec 2015 21:20:14 +0000 Subject: [PATCH] Reverting some of the latest code removals. --- trunk/dist/game/config/MMO.ini | 5 ++- trunk/dist/login/config/MMO.ini | 5 ++- trunk/java/com/l2jserver/Config.java | 3 ++ .../commons/mmocore/MMOConnection.java | 14 +++++++-- .../commons/mmocore/SelectorConfig.java | 10 ++++++ .../commons/mmocore/SelectorThread.java | 31 +++++++++++++------ .../com/l2jserver/gameserver/GameServer.java | 1 + 7 files changed, 54 insertions(+), 15 deletions(-) diff --git a/trunk/dist/game/config/MMO.ini b/trunk/dist/game/config/MMO.ini index 1a2ee693eb..83419c27a9 100644 --- a/trunk/dist/game/config/MMO.ini +++ b/trunk/dist/game/config/MMO.ini @@ -18,4 +18,7 @@ MaxReadPerPass = 12 # Each unfinished read/write need a TEMP storage Buffer # on large player amount we need more Buffers # if there are not enough buffers new ones are generated but not stored for future usage -HelperBufferCount = 20 \ No newline at end of file +HelperBufferCount = 20 + +# Setting this to True will lower your ping, at the cost of an increase in bandwidth consumption. +TcpNoDelay = True \ No newline at end of file diff --git a/trunk/dist/login/config/MMO.ini b/trunk/dist/login/config/MMO.ini index 1a2ee693eb..83419c27a9 100644 --- a/trunk/dist/login/config/MMO.ini +++ b/trunk/dist/login/config/MMO.ini @@ -18,4 +18,7 @@ MaxReadPerPass = 12 # Each unfinished read/write need a TEMP storage Buffer # on large player amount we need more Buffers # if there are not enough buffers new ones are generated but not stored for future usage -HelperBufferCount = 20 \ No newline at end of file +HelperBufferCount = 20 + +# Setting this to True will lower your ping, at the cost of an increase in bandwidth consumption. +TcpNoDelay = True \ No newline at end of file diff --git a/trunk/java/com/l2jserver/Config.java b/trunk/java/com/l2jserver/Config.java index bfa9e893b0..3354a69e2a 100644 --- a/trunk/java/com/l2jserver/Config.java +++ b/trunk/java/com/l2jserver/Config.java @@ -1002,6 +1002,7 @@ public final class Config public static int MMO_MAX_SEND_PER_PASS; public static int MMO_MAX_READ_PER_PASS; public static int MMO_HELPER_BUFFER_COUNT; + public static boolean MMO_TCP_NODELAY; // -------------------------------------------------- // Vitality Settings @@ -1749,6 +1750,7 @@ public final class Config MMO_MAX_SEND_PER_PASS = mmoSettings.getInt("MaxSendPerPass", 12); MMO_MAX_READ_PER_PASS = mmoSettings.getInt("MaxReadPerPass", 12); MMO_HELPER_BUFFER_COUNT = mmoSettings.getInt("HelperBufferCount", 20); + MMO_TCP_NODELAY = mmoSettings.getBoolean("TcpNoDelay", false); // Load IdFactory L2Properties file (if exists) final PropertiesParser IdFactory = new PropertiesParser(ID_CONFIG_FILE); @@ -2956,6 +2958,7 @@ public final class Config MMO_MAX_SEND_PER_PASS = mmoSettings.getInt("MaxSendPerPass", 12); MMO_MAX_READ_PER_PASS = mmoSettings.getInt("MaxReadPerPass", 12); MMO_HELPER_BUFFER_COUNT = mmoSettings.getInt("HelperBufferCount", 20); + MMO_TCP_NODELAY = mmoSettings.getBoolean("TcpNoDelay", false); // Load Telnet L2Properties file (if exists) final PropertiesParser telnetSettings = new PropertiesParser(TELNET_FILE); diff --git a/trunk/java/com/l2jserver/commons/mmocore/MMOConnection.java b/trunk/java/com/l2jserver/commons/mmocore/MMOConnection.java index 31502e2a1b..81fc9e6a21 100644 --- a/trunk/java/com/l2jserver/commons/mmocore/MMOConnection.java +++ b/trunk/java/com/l2jserver/commons/mmocore/MMOConnection.java @@ -20,6 +20,7 @@ package com.l2jserver.commons.mmocore; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; +import java.net.SocketException; import java.nio.ByteBuffer; import java.nio.channels.CancelledKeyException; import java.nio.channels.ReadableByteChannel; @@ -48,8 +49,6 @@ public class MMOConnection> private final SelectionKey _selectionKey; - // private SendablePacket _closePacket; - private ByteBuffer _readBuffer; private ByteBuffer _primaryWriteBuffer; @@ -60,7 +59,7 @@ public class MMOConnection> private T _client; - public MMOConnection(final SelectorThread selectorThread, final Socket socket, final SelectionKey key) + public MMOConnection(final SelectorThread selectorThread, final Socket socket, final SelectionKey key, boolean tcpNoDelay) { _selectorThread = selectorThread; _socket = socket; @@ -71,6 +70,15 @@ public class MMOConnection> _selectionKey = key; _sendQueue = new NioNetStackList<>(); + + try + { + _socket.setTcpNoDelay(tcpNoDelay); + } + catch (SocketException e) + { + e.printStackTrace(); + } } final void setClient(final T client) diff --git a/trunk/java/com/l2jserver/commons/mmocore/SelectorConfig.java b/trunk/java/com/l2jserver/commons/mmocore/SelectorConfig.java index 5bc7ca4dd5..84f471776a 100644 --- a/trunk/java/com/l2jserver/commons/mmocore/SelectorConfig.java +++ b/trunk/java/com/l2jserver/commons/mmocore/SelectorConfig.java @@ -51,4 +51,14 @@ public final class SelectorConfig * 10-30 for an latency/troughput trade-off based on your needs.
*/ public int SLEEP_TIME = 10; + + /** + * Used to enable/disable TCP_NODELAY which disable/enable Nagle's algorithm.
+ *
+ * Nagle's algorithm try to conserve bandwidth by minimizing the number of segments that are sent. When applications wish to decrease network latency and increase performance, they can disable Nagle's algorithm (that is enable TCP_NODELAY). Data will be sent earlier, at the cost of an increase + * in bandwidth consumption. The Nagle's algorithm is described in RFC 896.
+ *
+ * Summary, data will be sent earlier, thus lowering the ping, at the cost of a small increase in bandwidth consumption. + */ + public boolean TCP_NODELAY = true; } diff --git a/trunk/java/com/l2jserver/commons/mmocore/SelectorThread.java b/trunk/java/com/l2jserver/commons/mmocore/SelectorThread.java index 9a0c15a40d..7d3edd8c29 100644 --- a/trunk/java/com/l2jserver/commons/mmocore/SelectorThread.java +++ b/trunk/java/com/l2jserver/commons/mmocore/SelectorThread.java @@ -33,7 +33,7 @@ import java.util.LinkedList; /** * Parts of design based on network core from WoodenGil * @param - * @author KenM, Zoey76 + * @author KenM */ public final class SelectorThread> extends Thread { @@ -54,6 +54,7 @@ public final class SelectorThread> extends Thread private final int MAX_SEND_PER_PASS; private final int MAX_READ_PER_PASS; private final long SLEEP_TIME; + public boolean TCP_NODELAY; // Main Buffers private final ByteBuffer DIRECT_WRITE_BUFFER; private final ByteBuffer WRITE_BUFFER; @@ -76,6 +77,7 @@ public final class SelectorThread> extends Thread MAX_SEND_PER_PASS = sc.MAX_SEND_PER_PASS; MAX_READ_PER_PASS = sc.MAX_READ_PER_PASS; SLEEP_TIME = sc.SLEEP_TIME; + TCP_NODELAY = sc.TCP_NODELAY; DIRECT_WRITE_BUFFER = ByteBuffer.allocateDirect(sc.WRITE_BUFFER_SIZE).order(BYTE_ORDER); WRITE_BUFFER = ByteBuffer.wrap(new byte[sc.WRITE_BUFFER_SIZE]).order(BYTE_ORDER); @@ -198,9 +200,16 @@ public final class SelectorThread> extends Thread { while (!_pendingClose.isEmpty()) { - con = _pendingClose.removeFirst(); - writeClosePacket(con); - closeConnectionImpl(con.getSelectionKey(), con); + try + { + con = _pendingClose.removeFirst(); + writeClosePacket(con); + closeConnectionImpl(con.getSelectionKey(), con); + } + catch (Exception e) + { + e.printStackTrace(); + } } } @@ -249,7 +258,7 @@ public final class SelectorThread> extends Thread { sc.configureBlocking(false); SelectionKey clientKey = sc.register(_selector, SelectionKey.OP_READ); - con = new MMOConnection<>(this, sc.socket(), clientKey); + con = new MMOConnection<>(this, sc.socket(), clientKey, TCP_NODELAY); con.setClient(_clientFactory.create(con)); clientKey.attach(con); } @@ -275,9 +284,7 @@ public final class SelectorThread> extends Thread buf = READ_BUFFER; } - // if we try to to do a read with no space in the buffer it will - // read 0 bytes - // going into infinite loop + // if we try to to do a read with no space in the buffer it will read 0 bytes going into infinite loop if (buf.position() == buf.limit()) { System.exit(0); @@ -348,9 +355,9 @@ public final class SelectorThread> extends Thread switch (buf.remaining()) { case 0: - // buffer is full - // nothing to read + // buffer is full nothing to read return false; + case 1: // we don`t have enough data for header so we need to read key.interestOps(key.interestOps() | SelectionKey.OP_READ); @@ -367,6 +374,7 @@ public final class SelectorThread> extends Thread buf.compact(); } return false; + default: // data size excluding header size :> final int dataPending = (buf.getShort() & 0xFFFF) - HEADER_SIZE; @@ -398,6 +406,7 @@ public final class SelectorThread> extends Thread } return true; } + // we don`t have enough bytes for the dataPacket so we need // to read key.interestOps(key.interestOps() | SelectionKey.OP_READ); @@ -604,6 +613,8 @@ public final class SelectorThread> extends Thread // set the write buffer sp._buf = WRITE_BUFFER; + // set the client. + sp._client = client; // write content to buffer sp.write(); // delete the write buffer diff --git a/trunk/java/com/l2jserver/gameserver/GameServer.java b/trunk/java/com/l2jserver/gameserver/GameServer.java index 422b2c0208..7a2b271054 100644 --- a/trunk/java/com/l2jserver/gameserver/GameServer.java +++ b/trunk/java/com/l2jserver/gameserver/GameServer.java @@ -428,6 +428,7 @@ public final class GameServer sc.MAX_SEND_PER_PASS = Config.MMO_MAX_SEND_PER_PASS; sc.SLEEP_TIME = Config.MMO_SELECTOR_SLEEP_TIME; sc.HELPER_BUFFER_COUNT = Config.MMO_HELPER_BUFFER_COUNT; + sc.TCP_NODELAY = Config.MMO_TCP_NODELAY; _gamePacketHandler = new L2GamePacketHandler(); _selectorThread = new SelectorThread<>(sc, _gamePacketHandler, _gamePacketHandler, _gamePacketHandler, new IPv4Filter());