mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-11-15 11:39:11 +03:00
Merge branch 'feature/netty-client' into dev
This commit is contained in:
commit
43c44446d9
11 changed files with 257 additions and 65 deletions
|
@ -20,9 +20,9 @@
|
||||||
-keepattributes Signature
|
-keepattributes Signature
|
||||||
-adaptresourcefilecontents META-INF/MANIFEST.MF
|
-adaptresourcefilecontents META-INF/MANIFEST.MF
|
||||||
|
|
||||||
-keeppackagenames com.mojang.**,net.minecraftforge.fml.**,cpw.mods.fml.**,oshi.**,com.sun.jna.**,com.google.gson.**,org.slf4j.**,oshi.jna.**,com.sun.jna.**,org.apache.commons.logging.**, org.fusesource.**, com.jfoenix.**
|
-keeppackagenames com.mojang.**,net.minecraftforge.fml.**,cpw.mods.fml.**,com.google.gson.**,ru.gravit.repackage.**,org.fusesource.**
|
||||||
|
|
||||||
-keep class com.mojang.**,net.minecraftforge.fml.**,cpw.mods.fml.**,oshi.**,com.sun.jna.**,com.google.gson.**,org.slf4j.**,oshi.jna.**,com.sun.jna.**,org.apache.commons.logging.**, org.fusesource.**, com.jfoenix.** {
|
-keep class com.mojang.**,net.minecraftforge.fml.**,cpw.mods.fml.**,com.google.gson.**,ru.gravit.repackage.**,org.fusesource.** {
|
||||||
*;
|
*;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,16 +30,18 @@
|
||||||
shadowJar {
|
shadowJar {
|
||||||
classifier = null
|
classifier = null
|
||||||
relocate 'org.objectweb.asm', 'ru.gravit.repackage.org.objectweb.asm'
|
relocate 'org.objectweb.asm', 'ru.gravit.repackage.org.objectweb.asm'
|
||||||
|
relocate 'io.netty', 'ru.gravit.repackage.io.netty'
|
||||||
configurations = [project.configurations.pack]
|
configurations = [project.configurations.pack]
|
||||||
exclude 'module-info.class'
|
exclude 'module-info.class'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
pack project(':LauncherAPI') // Not error on obf.
|
pack project(':LauncherAPI')
|
||||||
bundle 'com.github.oshi:oshi-core:3.13.0'
|
bundle 'com.github.oshi:oshi-core:3.13.0'
|
||||||
bundle 'com.jfoenix:jfoenix:8.0.8'
|
bundle 'com.jfoenix:jfoenix:8.0.8'
|
||||||
bundle 'de.jensd:fontawesomefx:8.9'
|
bundle 'de.jensd:fontawesomefx:8.9'
|
||||||
bundle 'org.fusesource.jansi:jansi:1.17.1'
|
bundle 'org.apache.httpcomponents:httpclient:4.5.7'
|
||||||
|
pack 'io.netty:netty-all:4.1.32.Final'
|
||||||
pack 'org.ow2.asm:asm-tree:7.1'
|
pack 'org.ow2.asm:asm-tree:7.1'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
import ru.gravit.launcher.managers.ClientGsonManager;
|
import ru.gravit.launcher.managers.ClientGsonManager;
|
||||||
import ru.gravit.launcher.managers.ConsoleManager;
|
import ru.gravit.launcher.managers.ConsoleManager;
|
||||||
import ru.gravit.launcher.request.Request;
|
import ru.gravit.launcher.request.Request;
|
||||||
|
import ru.gravit.launcher.request.RequestException;
|
||||||
import ru.gravit.launcher.request.auth.RestoreSessionRequest;
|
import ru.gravit.launcher.request.auth.RestoreSessionRequest;
|
||||||
import ru.gravit.launcher.request.websockets.StandartClientWebSocketService;
|
import ru.gravit.launcher.request.websockets.StandartClientWebSocketService;
|
||||||
import ru.gravit.utils.helper.CommonHelper;
|
import ru.gravit.utils.helper.CommonHelper;
|
||||||
|
@ -81,10 +82,11 @@ public void start(String... args) throws Throwable {
|
||||||
{
|
{
|
||||||
LogHelper.debug("WebSocket connect closed. Try reconnect");
|
LogHelper.debug("WebSocket connect closed. Try reconnect");
|
||||||
try {
|
try {
|
||||||
if (!Request.service.reconnectBlocking()) LogHelper.error("Error connecting");
|
Request.service.open();
|
||||||
LogHelper.debug("Connect to %s", Launcher.getConfig().address);
|
LogHelper.debug("Connect to %s", Launcher.getConfig().address);
|
||||||
} catch (InterruptedException e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
LogHelper.error(e);
|
||||||
|
throw new RequestException(String.format("Connect error: %s", e.getMessage() != null ? e.getMessage() : "null"));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
RestoreSessionRequest request1 = new RestoreSessionRequest(Request.getSession());
|
RestoreSessionRequest request1 = new RestoreSessionRequest(Request.getSession());
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
import ru.gravit.launcher.profiles.ClientProfile;
|
import ru.gravit.launcher.profiles.ClientProfile;
|
||||||
import ru.gravit.launcher.profiles.PlayerProfile;
|
import ru.gravit.launcher.profiles.PlayerProfile;
|
||||||
import ru.gravit.launcher.request.Request;
|
import ru.gravit.launcher.request.Request;
|
||||||
|
import ru.gravit.launcher.request.RequestException;
|
||||||
import ru.gravit.launcher.request.auth.RestoreSessionRequest;
|
import ru.gravit.launcher.request.auth.RestoreSessionRequest;
|
||||||
import ru.gravit.launcher.serialize.HInput;
|
import ru.gravit.launcher.serialize.HInput;
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
import ru.gravit.launcher.serialize.HOutput;
|
||||||
|
@ -459,10 +460,11 @@ public static void main(String... args) throws Throwable {
|
||||||
{
|
{
|
||||||
LogHelper.debug("WebSocket connect closed. Try reconnect");
|
LogHelper.debug("WebSocket connect closed. Try reconnect");
|
||||||
try {
|
try {
|
||||||
if (!Request.service.reconnectBlocking()) LogHelper.error("Error connecting");
|
Request.service.open();
|
||||||
LogHelper.debug("Connect to %s", Launcher.getConfig().address);
|
LogHelper.debug("Connect to %s", Launcher.getConfig().address);
|
||||||
} catch (InterruptedException e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
LogHelper.error(e);
|
||||||
|
throw new RequestException(String.format("Connect error: %s", e.getMessage() != null ? e.getMessage() : "null"));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
RestoreSessionRequest request1 = new RestoreSessionRequest(Request.getSession());
|
RestoreSessionRequest request1 = new RestoreSessionRequest(Request.getSession());
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':libLauncher')
|
compile project(':libLauncher')
|
||||||
compile 'org.java-websocket:Java-WebSocket:1.3.9'
|
compileOnly 'io.netty:netty-all:4.1.32.Final'
|
||||||
compile 'org.apache.httpcomponents:httpclient:4.5.7'
|
compileOnly 'org.apache.httpcomponents:httpclient:4.5.7'
|
||||||
compileOnly 'com.google.guava:guava:26.0-jre'
|
compileOnly 'com.google.guava:guava:26.0-jre'
|
||||||
compile files('../compat/authlib/authlib-clean.jar')
|
compile files('../compat/authlib/authlib-clean.jar')
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +1,101 @@
|
||||||
package ru.gravit.launcher.request.websockets;
|
package ru.gravit.launcher.request.websockets;
|
||||||
|
|
||||||
import org.java_websocket.client.WebSocketClient;
|
import io.netty.bootstrap.Bootstrap;
|
||||||
import org.java_websocket.drafts.Draft_6455;
|
import io.netty.channel.*;
|
||||||
import org.java_websocket.handshake.ServerHandshake;
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
|
import io.netty.channel.socket.SocketChannel;
|
||||||
|
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||||
|
import io.netty.handler.codec.http.EmptyHttpHeaders;
|
||||||
|
import io.netty.handler.codec.http.HttpClientCodec;
|
||||||
|
import io.netty.handler.codec.http.HttpObjectAggregator;
|
||||||
|
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
|
||||||
|
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
|
||||||
|
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
|
||||||
|
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
|
||||||
|
import io.netty.handler.ssl.SslContext;
|
||||||
|
import io.netty.handler.ssl.SslContextBuilder;
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
import ru.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLException;
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class ClientJSONPoint extends WebSocketClient {
|
public abstract class ClientJSONPoint {
|
||||||
|
|
||||||
public ClientJSONPoint(URI serverUri, Map<String, String> httpHeaders, int connectTimeout) {
|
private final URI uri;
|
||||||
super(serverUri, new Draft_6455(), httpHeaders, connectTimeout);
|
protected Channel ch;
|
||||||
|
private static final EventLoopGroup group = new NioEventLoopGroup();
|
||||||
|
protected WebSocketClientHandler webSocketClientHandler;
|
||||||
|
protected Bootstrap bootstrap = new Bootstrap();
|
||||||
|
public boolean isClosed;
|
||||||
|
|
||||||
|
public ClientJSONPoint(final String uri) throws SSLException {
|
||||||
|
this(URI.create(uri));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ClientJSONPoint(URI uri) throws SSLException {
|
||||||
|
this.uri = uri;
|
||||||
|
String protocol = uri.getScheme();
|
||||||
|
if (!"ws".equals(protocol) && !"wss".equals(protocol)) {
|
||||||
|
throw new IllegalArgumentException("Unsupported protocol: " + protocol);
|
||||||
|
}
|
||||||
|
boolean ssl = false;
|
||||||
|
if("wss".equals(protocol))
|
||||||
|
{
|
||||||
|
ssl = true;
|
||||||
|
}
|
||||||
|
final SslContext sslCtx;
|
||||||
|
if (ssl) {
|
||||||
|
sslCtx = SslContextBuilder.forClient().build();
|
||||||
|
} else sslCtx = null;
|
||||||
|
bootstrap.group(group)
|
||||||
|
.channel(NioSocketChannel.class)
|
||||||
|
.handler(new ChannelInitializer<SocketChannel>() {
|
||||||
@Override
|
@Override
|
||||||
public void onOpen(ServerHandshake handshakedata) {
|
public void initChannel(SocketChannel ch) throws Exception {
|
||||||
|
ChannelPipeline pipeline = ch.pipeline();
|
||||||
|
if (sslCtx != null) {
|
||||||
|
pipeline.addLast(sslCtx.newHandler(ch.alloc()));
|
||||||
|
}
|
||||||
|
pipeline.addLast("http-codec", new HttpClientCodec());
|
||||||
|
pipeline.addLast("aggregator", new HttpObjectAggregator(65536));
|
||||||
|
pipeline.addLast("ws-handler", webSocketClientHandler);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void open() throws Exception {
|
||||||
public void onMessage(String message) {
|
//System.out.println("WebSocket Client connecting");
|
||||||
|
webSocketClientHandler =
|
||||||
|
new WebSocketClientHandler(
|
||||||
|
WebSocketClientHandshakerFactory.newHandshaker(
|
||||||
|
uri, WebSocketVersion.V13, null, false, EmptyHttpHeaders.INSTANCE, 1280000), this);
|
||||||
|
ch = bootstrap.connect(uri.getHost(), uri.getPort()).sync().channel();
|
||||||
|
webSocketClientHandler.handshakeFuture().sync();
|
||||||
|
}
|
||||||
|
public ChannelFuture send(String text)
|
||||||
|
{
|
||||||
|
LogHelper.dev("Send: %s", text);
|
||||||
|
return ch.writeAndFlush(new TextWebSocketFrame(text));
|
||||||
|
}
|
||||||
|
abstract void onMessage(String message) throws Exception;
|
||||||
|
abstract void onDisconnect() throws Exception;
|
||||||
|
abstract void onOpen() throws Exception;
|
||||||
|
|
||||||
|
public void close() throws InterruptedException {
|
||||||
|
//System.out.println("WebSocket Client sending close");
|
||||||
|
isClosed = true;
|
||||||
|
if(ch != null && ch.isActive())
|
||||||
|
{
|
||||||
|
ch.writeAndFlush(new CloseWebSocketFrame());
|
||||||
|
ch.closeFuture().sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
//group.shutdownGracefully();
|
||||||
public void onClose(int code, String reason, boolean remote) {
|
|
||||||
LogHelper.debug("Disconnected: " + code + " " + remote + " " + reason != null ? reason : "no reason");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void eval(final String text) throws IOException {
|
||||||
public void onError(Exception ex) {
|
ch.writeAndFlush(new TextWebSocketFrame(text));
|
||||||
LogHelper.error(ex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import org.java_websocket.handshake.ServerHandshake;
|
|
||||||
import ru.gravit.launcher.events.ExceptionEvent;
|
import ru.gravit.launcher.events.ExceptionEvent;
|
||||||
import ru.gravit.launcher.events.request.*;
|
import ru.gravit.launcher.events.request.*;
|
||||||
import ru.gravit.launcher.hasher.HashedEntry;
|
import ru.gravit.launcher.hasher.HashedEntry;
|
||||||
|
@ -10,10 +9,10 @@
|
||||||
import ru.gravit.launcher.request.ResultInterface;
|
import ru.gravit.launcher.request.ResultInterface;
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
import ru.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
@ -27,8 +26,8 @@ public class ClientWebSocketService extends ClientJSONPoint {
|
||||||
private HashMap<String, Class<? extends ResultInterface>> results;
|
private HashMap<String, Class<? extends ResultInterface>> results;
|
||||||
private HashSet<EventHandler> handlers;
|
private HashSet<EventHandler> handlers;
|
||||||
|
|
||||||
public ClientWebSocketService(GsonBuilder gsonBuilder, String address, int i) {
|
public ClientWebSocketService(GsonBuilder gsonBuilder, String address, int i) throws SSLException {
|
||||||
super(createURL(address), Collections.emptyMap(), i);
|
super(createURL(address));
|
||||||
requests = new HashMap<>();
|
requests = new HashMap<>();
|
||||||
results = new HashMap<>();
|
results = new HashMap<>();
|
||||||
handlers = new HashSet<>();
|
handlers = new HashSet<>();
|
||||||
|
@ -51,7 +50,7 @@ private static URI createURL(String address) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMessage(String message) {
|
void onMessage(String message) {
|
||||||
ResultInterface result = gson.fromJson(message, ResultInterface.class);
|
ResultInterface result = gson.fromJson(message, ResultInterface.class);
|
||||||
for (EventHandler handler : handlers) {
|
for (EventHandler handler : handlers) {
|
||||||
handler.process(result);
|
handler.process(result);
|
||||||
|
@ -59,25 +58,19 @@ public void onMessage(String message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(Exception e) {
|
void onDisconnect() {
|
||||||
LogHelper.error(e);
|
LogHelper.info("WebSocket client disconnect");
|
||||||
|
if(onCloseCallback != null) onCloseCallback.onClose(0,"unsupported param", !isClosed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onOpen(ServerHandshake handshakedata) {
|
void onOpen() throws Exception {
|
||||||
//Notify open
|
|
||||||
synchronized (onConnect)
|
synchronized (onConnect)
|
||||||
{
|
{
|
||||||
onConnect.notifyAll();
|
onConnect.notifyAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClose(int code, String reason, boolean remote)
|
|
||||||
{
|
|
||||||
LogHelper.debug("Disconnected: " + code + " " + remote + " " + (reason != null ? reason : "no reason"));
|
|
||||||
if(onCloseCallback != null)
|
|
||||||
onCloseCallback.onClose(code, reason, remote);
|
|
||||||
}
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface OnCloseCallback
|
public interface OnCloseCallback
|
||||||
{
|
{
|
||||||
|
@ -136,7 +129,7 @@ public void registerHandler(EventHandler eventHandler) {
|
||||||
}
|
}
|
||||||
public void waitIfNotConnected()
|
public void waitIfNotConnected()
|
||||||
{
|
{
|
||||||
if(!isOpen() && !isClosed() && !isClosing())
|
/*if(!isOpen() && !isClosed() && !isClosing())
|
||||||
{
|
{
|
||||||
LogHelper.warning("WebSocket not connected. Try wait onConnect object");
|
LogHelper.warning("WebSocket not connected. Try wait onConnect object");
|
||||||
synchronized (onConnect)
|
synchronized (onConnect)
|
||||||
|
@ -147,20 +140,22 @@ public void waitIfNotConnected()
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendObject(Object obj) throws IOException {
|
public void sendObject(Object obj) throws IOException {
|
||||||
waitIfNotConnected();
|
waitIfNotConnected();
|
||||||
if(isClosed() && reconnectCallback != null)
|
if(ch == null || !ch.isActive()) reconnectCallback.onReconnect();
|
||||||
reconnectCallback.onReconnect();
|
//if(isClosed() && reconnectCallback != null)
|
||||||
|
// reconnectCallback.onReconnect();
|
||||||
send(gson.toJson(obj, RequestInterface.class));
|
send(gson.toJson(obj, RequestInterface.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendObject(Object obj, Type type) throws IOException {
|
public void sendObject(Object obj, Type type) throws IOException {
|
||||||
waitIfNotConnected();
|
waitIfNotConnected();
|
||||||
if(isClosed() && reconnectCallback != null)
|
if(ch == null || !ch.isActive()) reconnectCallback.onReconnect();
|
||||||
reconnectCallback.onReconnect();
|
//if(isClosed() && reconnectCallback != null)
|
||||||
|
// reconnectCallback.onReconnect();
|
||||||
send(gson.toJson(obj, type));
|
send(gson.toJson(obj, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
import ru.gravit.utils.helper.JVMHelper;
|
import ru.gravit.utils.helper.JVMHelper;
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
import ru.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
@ -15,7 +16,7 @@
|
||||||
|
|
||||||
public class StandartClientWebSocketService extends ClientWebSocketService {
|
public class StandartClientWebSocketService extends ClientWebSocketService {
|
||||||
public WaitEventHandler waitEventHandler = new WaitEventHandler();
|
public WaitEventHandler waitEventHandler = new WaitEventHandler();
|
||||||
public StandartClientWebSocketService(GsonBuilder gsonBuilder, String address, int i) {
|
public StandartClientWebSocketService(GsonBuilder gsonBuilder, String address, int i) throws SSLException {
|
||||||
super(gsonBuilder, address, i);
|
super(gsonBuilder, address, i);
|
||||||
}
|
}
|
||||||
public class RequestFuture implements Future<ResultInterface>
|
public class RequestFuture implements Future<ResultInterface>
|
||||||
|
@ -101,27 +102,38 @@ public RequestFuture asyncSendRequest(RequestInterface request) throws IOExcepti
|
||||||
}
|
}
|
||||||
|
|
||||||
public static StandartClientWebSocketService initWebSockets(String address, boolean async) {
|
public static StandartClientWebSocketService initWebSockets(String address, boolean async) {
|
||||||
StandartClientWebSocketService service = new StandartClientWebSocketService(new GsonBuilder(), address, 5000);
|
StandartClientWebSocketService service;
|
||||||
|
try {
|
||||||
|
service = new StandartClientWebSocketService(new GsonBuilder(), address, 5000);
|
||||||
|
} catch (SSLException e) {
|
||||||
|
LogHelper.error(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
service.registerResults();
|
service.registerResults();
|
||||||
service.registerRequests();
|
service.registerRequests();
|
||||||
service.registerHandler(service.waitEventHandler);
|
service.registerHandler(service.waitEventHandler);
|
||||||
if(!async)
|
if(!async)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (!service.connectBlocking()) LogHelper.error("Error connecting");
|
service.open();
|
||||||
LogHelper.debug("Connect to %s", address);
|
LogHelper.debug("Connect to %s", address);
|
||||||
} catch (InterruptedException e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
service.connect();
|
try {
|
||||||
|
service.open();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
JVMHelper.RUNTIME.addShutdownHook(new Thread(() -> {
|
JVMHelper.RUNTIME.addShutdownHook(new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
if(service.isOpen())
|
//if(service.isOpen())
|
||||||
service.closeBlocking();
|
// service.closeBlocking();
|
||||||
|
service.close();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
package ru.gravit.launcher.request.websockets;
|
||||||
|
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.channel.ChannelFuture;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.channel.ChannelPromise;
|
||||||
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
|
import io.netty.handler.codec.http.FullHttpResponse;
|
||||||
|
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
|
||||||
|
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
|
||||||
|
import io.netty.handler.codec.http.websocketx.PongWebSocketFrame;
|
||||||
|
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
|
||||||
|
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
|
||||||
|
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
|
||||||
|
import io.netty.util.CharsetUtil;
|
||||||
|
import ru.gravit.utils.helper.LogHelper;
|
||||||
|
public class WebSocketClientHandler extends SimpleChannelInboundHandler<Object> {
|
||||||
|
|
||||||
|
private final WebSocketClientHandshaker handshaker;
|
||||||
|
private final ClientJSONPoint clientJSONPoint;
|
||||||
|
private ChannelPromise handshakeFuture;
|
||||||
|
|
||||||
|
public WebSocketClientHandler(final WebSocketClientHandshaker handshaker, ClientJSONPoint clientJSONPoint) {
|
||||||
|
this.handshaker = handshaker;
|
||||||
|
this.clientJSONPoint = clientJSONPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChannelFuture handshakeFuture() {
|
||||||
|
return handshakeFuture;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handlerAdded(final ChannelHandlerContext ctx) throws Exception {
|
||||||
|
handshakeFuture = ctx.newPromise();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void channelActive(final ChannelHandlerContext ctx) throws Exception {
|
||||||
|
handshaker.handshake(ctx.channel());
|
||||||
|
clientJSONPoint.onOpen();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
|
||||||
|
//System.out.println("WebSocket Client disconnected!");
|
||||||
|
clientJSONPoint.onDisconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||||
|
final Channel ch = ctx.channel();
|
||||||
|
if (!handshaker.isHandshakeComplete()) {
|
||||||
|
// web socket client connected
|
||||||
|
handshaker.finishHandshake(ch, (FullHttpResponse) msg);
|
||||||
|
handshakeFuture.setSuccess();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg instanceof FullHttpResponse) {
|
||||||
|
final FullHttpResponse response = (FullHttpResponse) msg;
|
||||||
|
throw new Exception("Unexpected FullHttpResponse (getStatus=" + response.status() + ", content="
|
||||||
|
+ response.content().toString(CharsetUtil.UTF_8) + ')');
|
||||||
|
}
|
||||||
|
|
||||||
|
final WebSocketFrame frame = (WebSocketFrame) msg;
|
||||||
|
if (frame instanceof TextWebSocketFrame) {
|
||||||
|
final TextWebSocketFrame textFrame = (TextWebSocketFrame) frame;
|
||||||
|
clientJSONPoint.onMessage(textFrame.text());
|
||||||
|
LogHelper.dev("Message: %s", textFrame.text());
|
||||||
|
// uncomment to print request
|
||||||
|
// logger.info(textFrame.text());
|
||||||
|
} else if (frame instanceof PongWebSocketFrame) {
|
||||||
|
} else if (frame instanceof CloseWebSocketFrame)
|
||||||
|
ch.close();
|
||||||
|
else if (frame instanceof BinaryWebSocketFrame) {
|
||||||
|
// uncomment to print request
|
||||||
|
// logger.info(frame.content().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) throws Exception {
|
||||||
|
LogHelper.error(cause);
|
||||||
|
|
||||||
|
if (!handshakeFuture.isDone()) {
|
||||||
|
handshakeFuture.setFailure(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.close();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,12 @@
|
||||||
|
apply plugin: 'com.github.johnrengelman.shadow'
|
||||||
|
|
||||||
String mainClassName = "ru.gravit.launcher.server.ServerWrapper"
|
String mainClassName = "ru.gravit.launcher.server.ServerWrapper"
|
||||||
String mainAgentName = "ru.gravit.launcher.server.ServerAgent"
|
String mainAgentName = "ru.gravit.launcher.server.ServerAgent"
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
pack
|
||||||
|
compile.extendsFrom pack
|
||||||
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
|
@ -12,6 +18,7 @@
|
||||||
targetCompatibility = '1.8'
|
targetCompatibility = '1.8'
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
|
classifier = 'clean'
|
||||||
from { configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) } }
|
from { configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) } }
|
||||||
manifest.attributes("Main-Class": mainClassName,
|
manifest.attributes("Main-Class": mainClassName,
|
||||||
"Premain-Class": mainAgentName,
|
"Premain-Class": mainAgentName,
|
||||||
|
@ -21,5 +28,18 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':LauncherAPI')
|
pack project(':LauncherAPI')
|
||||||
|
pack 'org.apache.httpcomponents:httpclient:4.5.7'
|
||||||
|
pack 'io.netty:netty-all:4.1.32.Final'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shadowJar {
|
||||||
|
classifier = null
|
||||||
|
relocate 'io.netty', 'ru.gravit.repackage.io.netty'
|
||||||
|
configurations = [project.configurations.pack]
|
||||||
|
exclude 'module-info.class'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
build.dependsOn tasks.shadowJar
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
import ru.gravit.launcher.events.request.ProfilesRequestEvent;
|
import ru.gravit.launcher.events.request.ProfilesRequestEvent;
|
||||||
import ru.gravit.launcher.profiles.ClientProfile;
|
import ru.gravit.launcher.profiles.ClientProfile;
|
||||||
import ru.gravit.launcher.request.Request;
|
import ru.gravit.launcher.request.Request;
|
||||||
|
import ru.gravit.launcher.request.RequestException;
|
||||||
import ru.gravit.launcher.request.auth.AuthRequest;
|
import ru.gravit.launcher.request.auth.AuthRequest;
|
||||||
import ru.gravit.launcher.request.update.ProfilesRequest;
|
import ru.gravit.launcher.request.update.ProfilesRequest;
|
||||||
import ru.gravit.launcher.server.setup.ServerWrapperSetup;
|
import ru.gravit.launcher.server.setup.ServerWrapperSetup;
|
||||||
|
@ -162,10 +163,11 @@ public void run(String... args) throws Throwable {
|
||||||
{
|
{
|
||||||
LogHelper.debug("WebSocket connect closed. Try reconnect");
|
LogHelper.debug("WebSocket connect closed. Try reconnect");
|
||||||
try {
|
try {
|
||||||
if (!Request.service.reconnectBlocking()) LogHelper.error("Error connecting");
|
Request.service.open();
|
||||||
LogHelper.debug("Connect to %s", config.websocket.address);
|
LogHelper.debug("Connect to %s", config.websocket.address);
|
||||||
} catch (InterruptedException e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
LogHelper.error(e);
|
||||||
|
throw new RequestException(String.format("Connect error: %s", e.getMessage() != null ? e.getMessage() : "null"));
|
||||||
}
|
}
|
||||||
auth();
|
auth();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue