Skip to content

Commit

Permalink
add udpOrTcpTransport (#102)
Browse files Browse the repository at this point in the history
* add udpOrTcpTransport

* update

* add unit test
  • Loading branch information
tvd12 authored Jul 12, 2022
1 parent 1cb3406 commit a131e6c
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ public EzyAppSendResponseImpl(EzyAppContext context) {
public void execute(
EzyData data,
EzySession recipient,
boolean encrypted, EzyTransportType transportType) {
boolean encrypted,
EzyTransportType transportType
) {
EzyResponse response = newResponse(data);
serverContext.send(response, recipient, encrypted, transportType);
}
Expand All @@ -34,7 +36,9 @@ public void execute(
public void execute(
EzyData data,
Collection<EzySession> recipients,
boolean encrypted, EzyTransportType transportType) {
boolean encrypted,
EzyTransportType transportType
) {
EzyResponse response = newResponse(data);
serverContext.send(response, recipients, encrypted, transportType);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
public enum EzyTransportType implements EzyConstant {

TCP(1),
UDP(2);
UDP(2),
UDP_OR_TCP(3);

@Getter
private final int id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,15 @@ protected final void executeSendingPacket(EzyPacket packet, Object writeBuffer)
try {
EzyChannel channel = session.getChannel();
if (canWriteBytes(channel)) {
int writeBytes;
if (packet.getTransportType() == EzyTransportType.TCP) {
writeBytes = writePacketToSocket(packet, writeBuffer);
} else {
writeBytes = writeUdpPacketToSocket(packet, writeBuffer);
EzyConstant transportType = packet.getTransportType();
if (transportType == EzyTransportType.UDP_OR_TCP) {
transportType = session.getDatagramChannelPool() != null
? EzyTransportType.UDP
: EzyTransportType.TCP;
}
int writeBytes = transportType == EzyTransportType.TCP
? writePacketToSocket(packet, writeBuffer)
: writeUdpPacketToSocket(packet, writeBuffer);
executeAddWrittenBytes(writeBytes);
}
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@
import com.tvd12.ezyfox.util.EzyDestroyable;
import com.tvd12.ezyfoxserver.EzySimpleServer;
import com.tvd12.ezyfoxserver.api.EzyResponseApi;
import com.tvd12.ezyfoxserver.constant.EzyCommand;
import com.tvd12.ezyfoxserver.constant.EzyConnectionType;
import com.tvd12.ezyfoxserver.constant.EzyDisconnectReason;
import com.tvd12.ezyfoxserver.constant.EzyMaxRequestPerSecondAction;
import com.tvd12.ezyfoxserver.config.EzySimpleConfig;
import com.tvd12.ezyfoxserver.constant.*;
import com.tvd12.ezyfoxserver.context.EzySimpleServerContext;
import com.tvd12.ezyfoxserver.entity.EzySession;
import com.tvd12.ezyfoxserver.nio.entity.EzyNioSession;
Expand Down Expand Up @@ -353,6 +351,146 @@ private ExHandlerGroup newHandlerGroup() throws Exception {
.build();
}

@Test
public void executeSendingPacketWithTransportTypeWithUdpOrTcpActualUdp() throws Exception {
// given
EzyStatistics statistics = new EzySimpleStatistics();
EzySimpleSettings settings = new EzySimpleSettings();
EzySimpleStreamingSetting streaming = settings.getStreaming();
streaming.setEnable(true);
EzySimpleServer server = new EzySimpleServer();
server.setSettings(settings);
EzySimpleConfig config = new EzySimpleConfig();
server.setConfig(config);

EzySimpleServerContext serverContext = new EzySimpleServerContext();
serverContext.setServer(server);
serverContext.init();

EzyChannel channel = mock(EzyChannel.class);
when(channel.isConnected()).thenReturn(true);
when(channel.getConnection()).thenReturn(SocketChannel.open());
when(channel.getConnectionType()).thenReturn(EzyConnectionType.SOCKET);
when(channel.write(any(ByteBuffer.class), anyBoolean())).thenReturn(123456);

EzySimpleSession session = mock(EzySimpleSession.class);
when(session.getChannel()).thenReturn(channel);

EzyDatagramChannelPool datagramChannelPool =
mock(EzyDatagramChannelPool.class);
when(session.getDatagramChannelPool()).thenReturn(datagramChannelPool);

InetSocketAddress udpAddress = new InetSocketAddress("127.0.0.1", 12348);
when(session.getUdpClientAddress()).thenReturn(udpAddress);

ExEzyByteToObjectDecoder decoder = new ExEzyByteToObjectDecoder();
ExecutorService statsThreadPool = EzyExecutors.newFixedThreadPool(1, "stats");

EzySessionTicketsRequestQueues sessionTicketsRequestQueues =
mock(EzySessionTicketsRequestQueues.class);
when(sessionTicketsRequestQueues.addRequest(any())).thenReturn(false);
ExHandlerGroup group = (ExHandlerGroup) new ExHandlerGroup.Builder()
.session(session)
.decoder(decoder)
.sessionCount(new AtomicInteger())
.networkStats((EzyNetworkStats) statistics.getSocketStats().getNetworkStats())
.sessionStats((EzySessionStats) statistics.getSocketStats().getSessionStats())
.serverContext(serverContext)
.statsThreadPool(statsThreadPool)
.sessionTicketsRequestQueues(sessionTicketsRequestQueues)
.build();

EzyPacket packet = mock(EzyPacket.class);
when(
packet.getTransportType()
).thenReturn(EzyTransportType.UDP_OR_TCP);
when(packet.getData()).thenReturn(new byte[]{1, 2, 3});
ByteBuffer buffer = ByteBuffer.allocate(100);

// when
MethodInvoker.create()
.object(group)
.method("executeSendingPacket")
.param(EzyPacket.class, packet)
.param(Object.class, buffer)
.invoke();

Asserts.assertNotNull(group.getSession());

// then
verify(session, times(3)).getChannel();
verify(session, times(2)).getDatagramChannelPool();
verify(session, times(1)).getUdpClientAddress();
}

@Test
public void executeSendingPacketWithTransportTypeWithUdpOrTcpActualTcp() throws Exception {
// given
EzyStatistics statistics = new EzySimpleStatistics();
EzySimpleSettings settings = new EzySimpleSettings();
EzySimpleStreamingSetting streaming = settings.getStreaming();
streaming.setEnable(true);
EzySimpleServer server = new EzySimpleServer();
server.setSettings(settings);
EzySimpleConfig config = new EzySimpleConfig();
server.setConfig(config);

EzySimpleServerContext serverContext = new EzySimpleServerContext();
serverContext.setServer(server);
serverContext.init();

EzyChannel channel = mock(EzyChannel.class);
when(channel.isConnected()).thenReturn(true);
when(channel.getConnection()).thenReturn(SocketChannel.open());
when(channel.getConnectionType()).thenReturn(EzyConnectionType.SOCKET);
when(channel.write(any(ByteBuffer.class), anyBoolean())).thenReturn(123456);

EzySimpleSession session = mock(EzySimpleSession.class);
when(session.getChannel()).thenReturn(channel);

InetSocketAddress udpAddress = new InetSocketAddress("127.0.0.1", 12348);
when(session.getUdpClientAddress()).thenReturn(udpAddress);

ExEzyByteToObjectDecoder decoder = new ExEzyByteToObjectDecoder();
ExecutorService statsThreadPool = EzyExecutors.newFixedThreadPool(1, "stats");

EzySessionTicketsRequestQueues sessionTicketsRequestQueues =
mock(EzySessionTicketsRequestQueues.class);
when(sessionTicketsRequestQueues.addRequest(any())).thenReturn(false);
ExHandlerGroup group = (ExHandlerGroup) new ExHandlerGroup.Builder()
.session(session)
.decoder(decoder)
.sessionCount(new AtomicInteger())
.networkStats((EzyNetworkStats) statistics.getSocketStats().getNetworkStats())
.sessionStats((EzySessionStats) statistics.getSocketStats().getSessionStats())
.serverContext(serverContext)
.statsThreadPool(statsThreadPool)
.sessionTicketsRequestQueues(sessionTicketsRequestQueues)
.build();

EzyPacket packet = mock(EzyPacket.class);
when(
packet.getTransportType()
).thenReturn(EzyTransportType.UDP_OR_TCP);
when(packet.getData()).thenReturn(new byte[]{1, 2, 3});
ByteBuffer buffer = ByteBuffer.allocate(100);

// when
MethodInvoker.create()
.object(group)
.method("executeSendingPacket")
.param(EzyPacket.class, packet)
.param(Object.class, buffer)
.invoke();

Asserts.assertNotNull(group.getSession());

// then
verify(session, times(3)).getChannel();
verify(session, times(1)).getDatagramChannelPool();
verify(session, times(0)).getUdpClientAddress();
}

@SuppressWarnings("rawtypes")
public static class ExHandlerGroup
extends EzyAbstractHandlerGroup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,8 @@ default T usernames(Iterable<String> usernames) {
default T udpTransport() {
return transportType(EzyTransportType.UDP);
}

default T udpOrTcpTransport() {
return transportType(EzyTransportType.UDP_OR_TCP);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.tvd12.ezyfox.binding.EzyMarshaller;
import com.tvd12.ezyfox.collect.Sets;
import com.tvd12.ezyfoxserver.command.EzyResponse;
import com.tvd12.ezyfoxserver.constant.EzyTransportType;
import com.tvd12.ezyfoxserver.context.EzyContext;
import com.tvd12.ezyfoxserver.support.command.EzyAbstractObjectResponse;
import com.tvd12.ezyfoxserver.support.command.EzyObjectResponse;
Expand All @@ -11,7 +12,7 @@
import com.tvd12.test.util.RandomUtil;
import org.testng.annotations.Test;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.*;

public class EzyAbstractObjectResponseTest {

Expand Down Expand Up @@ -39,6 +40,29 @@ public void exclude2Times() {
);
}

@Test
public void udpOrTcpTransportTest() {
// given
EzyContext context = mock(EzyContext.class);
EzyMarshaller marshaller = mock(EzyMarshaller.class);

// when
EzyObjectResponse sut = new InternalObjectResponse(
context,
marshaller
)
.udpOrTcpTransport();

// then
EzyResponse response = FieldUtil.getFieldValue(
sut,
"response"
);
verify(response, times(1)).transportType(
EzyTransportType.UDP_OR_TCP
);
}

private static class InternalObjectResponse
extends EzyAbstractObjectResponse {

Expand All @@ -51,7 +75,10 @@ public InternalObjectResponse(

@Override
protected EzyResponse newResponse() {
return null;
if (response == null) {
response = mock(EzyResponse.class);
}
return response;
}
}
}

0 comments on commit a131e6c

Please sign in to comment.