Skip to content

Instantly share code, notes, and snippets.

@zibellon
Created September 21, 2019 10:38
Show Gist options
  • Save zibellon/d185ab3ad8eb53ee0938f79854b8b0cc to your computer and use it in GitHub Desktop.
Save zibellon/d185ab3ad8eb53ee0938f79854b8b0cc to your computer and use it in GitHub Desktop.
Отлов событий с сокет сервера и передача их в главное активити.
public class MySocket {
public enum SocketEventsEnum {
operationCreated,
operationComplete,
newMessage,
sameUserConnected
}
//Сам класс с сокетом
public static MySocket mySocket;
public Socket socket;
private boolean isConnected = false; //Подключен сокет или нет
private boolean isReg = false; //зареган он на серваке или нет!
private boolean needToSubscribe = true;
public PublishRelay<MySocketEvent> mySocketEventPublishRelay = PublishRelay.create();
public Disposable mySocketEventsDisposable; //Херня которая хранит в себе подписку на все события
public static Boolean firstStart = true; //первый запуск приложения или перезапуск!
public static void init() {
mySocket = new MySocket();
}
public static MySocket getInstance() {
return mySocket;
}
public void startSocket() {
IO.Options opts = new IO.Options();
opts.reconnection = true;
opts.forceNew = true;
try {
mySocket.socket = IO.socket("http://**.***.***.**", opts);
} catch (URISyntaxException e) {
e.printStackTrace();
}
mySocket.socket.on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
Log.d("SOCKET", "DISCONNECT");
isConnected = false;
}
}).on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
Log.d("SOCKET", "КОННЕКТ");
isConnected = true;
if (isReg) { //бЫл зареган клиент или нет до разрыва сети!
regClient();
}
subscribeAll(); //Сразу после коннекта вызываем подписку на все все
}
}).on(Socket.EVENT_RECONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
Log.d("SOCKET", "RECONNECT");
}
});
isReg = true; //Он у нас зареган
mySocket.socket.connect(); //Делаем коннект сокета
}
//Коннект сокета
public void regClient() {
Log.d("SOCKET", "РЕГ");
if (!isConnected) {
mySocket.socket.connect();
return;
}
Log.d("SOCKET", "РЕГ - ПОСЛЕ");
//Подключаемся как клиент
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("token", UserLocal.getInstance().getCustomToken());
Log.d("SOCKET", "РЕГ(ОТПРАВКА) = " + jsonObject);
mySocket.socket.emit("registration", jsonObject);
} catch (JSONException e) {
e.printStackTrace();
}
}
private void subscribeAll() {
if (!needToSubscribe) {
return;
}
needToSubscribe = false;
//Сокет на создание операции
mySocket.socket.on("operationCreated", new Emitter.Listener() {
@Override
public void call(Object... args) {
org.json.JSONObject json = (JSONObject) args[0];
JsonParser jsonParser = new JsonParser();
JsonObject gson = (JsonObject) jsonParser.parse(json.toString());
HyperLog.d("SOCKET", "Операция создана - " + gson);
mySocketEventPublishRelay.accept(new MySocketEvent(SocketEventsEnum.operationCreated, gson));
}
});
//Операция завершена
mySocket.socket.on("operationComplete", new Emitter.Listener() {
@Override
public void call(Object... args) {
org.json.JSONObject json = (JSONObject) args[0];
JsonParser jsonParser = new JsonParser();
JsonObject gson = (JsonObject) jsonParser.parse(json.toString());
HyperLog.d("SOCKET", "Операция завершена - " + gson);
mySocketEventPublishRelay.accept(new MySocketEvent(SocketEventsEnum.operationComplete, gson));
}
});
//Подписка но поступление новых сообщений
mySocket.socket.on("newMessage", new Emitter.Listener() {
@Override
public void call(Object... args) {
org.json.JSONObject json = (JSONObject) args[0];
JsonParser jsonParser = new JsonParser();
JsonObject gson = (JsonObject) jsonParser.parse(json.toString());
HyperLog.d("SOCKET", "Прилетело новое сообщение - " + gson);
mySocketEventPublishRelay.accept(new MySocketEvent(SocketEventsEnum.newMessage, gson));
}
});
//Подписка на подключение такого же пользователя
mySocket.socket.on("sameUserConnected", new Emitter.Listener() {
@Override
public void call(Object... args) {
org.json.JSONObject json = (JSONObject) args[0];
JsonParser jsonParser = new JsonParser();
JsonObject gson = (JsonObject) jsonParser.parse(json.toString());
HyperLog.d("SOCKET", "Вошел такой же пользователь - " + gson);
mySocketEventPublishRelay.accept(new MySocketEvent(SocketEventsEnum.sameUserConnected, gson));
}
});
}
public class MySocketEvent {
private SocketEventsEnum name;
private JsonElement jsonElement;
MySocketEvent(SocketEventsEnum name, JsonElement jsonElement) {
this.name = name;
this.jsonElement = jsonElement;
}
@Override
public String toString() {
return "MySocketEvent{" +
"name='" + name + '\'' +
", jsonElement=" + jsonElement+
'}';
}
public SocketEventsEnum getName() {
return name;
}
public JsonObject getAsObject() {
return jsonElement.getAsJsonObject();
}
public JsonArray getAsArray() {
return jsonElement.getAsJsonArray();
}
}
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// цвет статус бара
StatusBarUtil.setDarkMode(this);
StatusBarUtil.setColor(this, getResources().getColor(R.color.toolBarColor), 0);
RXData.contextBehaviorRelay.accept(this);
//Основной контейнер где хранится все
ViewGroup container = findViewById(R.id.controller_container);
CoordinatorMain.getInstance().setFullScreenContainer(container); //Сохраняем ссылку на полноэкранный контейнер!!!
CoordinatorMain.getInstance().setRootActivity(this); //Корневое активити - ну нужно
//Типо роутер.....
router = Conductor.attachRouter(this, container, savedInstanceState);
//Загоняем основной роутер в навигатор
CoordinatorMain.getInstance().setMainRouter(router);
//Выбираем рандомного оператора с которым будем общаться
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("router", "getRandomOperator");
NetClient.mainPost(jsonObject, new NetClient.NetClientListener<JsonObject>() {
@Override
public void dataReady(JsonObject data) {
Log.d(LOG, "Нвый рандомный оператор прилетел = " + data);
User user = DataManager.getInstance().parseUser(data);
if (user != null) {
UserLocal.getInstance().setOperatorHashId(user.getHashId());
}
}
});
//Первый запуск приложения
//Все по новой с чистого листа
if (MySocket.firstStart) {
MySocket.firstStart = false;
//Инит сокета
MySocket.init();
MySocket.getInstance().startSocket();
//Коннектим сокет
DataManager.getInstance().createNotificationChannel();
Intent serviceIntent = new Intent(this, MySocketService.class);
ContextCompat.startForegroundService(this, serviceIntent);
}
startNavigation();
socketStart();
//Если у на снет на устройстве интернета = то мы делаем блокировку всего интерфейса
compositeDisposable.add(ReactiveNetwork
.observeInternetConnectivity()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) throws Exception {
Log.d(LOG, "Унет есть = " + aBoolean);
if (!aBoolean) {
InstrumentsAlert.getInstance().showInternetBlockDialog();
} else {
InstrumentsAlert.getInstance().closeInternetBlockDialod();
}
}
}));
}
private void startNavigation() {
//Если нет Корневого компонента - то мы его херачим
if (!router.hasRootController()) {
router.setRoot(RouterTransaction.with(new BotNavScreen()));
}
}
//Все что связано с сокетом в начале )))
private void socketStart() {
//Сначала проводим отпу=иску от всех всего и вся
if (MySocket.getInstance().mySocketEventsDisposable != null) {
MySocket.getInstance().mySocketEventsDisposable.dispose();
}
//Подписка на сокет Евентс
MySocket.getInstance().mySocketEventsDisposable =
MySocket.getInstance().mySocketEventPublishRelay.observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<MySocket.MySocketEvent>() {
@Override
public void accept(MySocket.MySocketEvent mySocketEvent) {
HyperLog.d(LOG, "Из сокета = " + mySocketEvent.toString());
socketHelper(mySocketEvent);
}
});
}
private void socketHelper(final MySocket.MySocketEvent mySocketEvent) {
switch (mySocketEvent.getName()) {
case operationCreated: {
String text = "Продавец планирует списать с вас ";
text += mySocketEvent.getAsObject().get("operationSum").getAsString();
text += " руб.";
text += "\n\nПодтвердить?";
//Диалог кастомный
InstrumentsAlert.getInstance().showImageAlert(
InstrumentsAlert.AlertTypesEnum.Attention,
text,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//Жмяк ок - диалок с выбором списка
//Выбираем пользователя и все его аккаунты
final User user = (User) RealmControl.getInstance().getObjById(User.class, "hashId", UserLocal.getInstance().getHashId());
//У пользователя нет компании
//Сразу списываем деньги с дебетовой карты
if (user.getCompany() == null) {
final JsonObject sendJson = new JsonObject();
sendJson.addProperty("router", "confirmOperation");
sendJson.addProperty("senderAccountHashId", user.getAccounts().get(0).getHashId());
sendJson.addProperty("operationHashId", mySocketEvent.getAsObject().get("operationId").getAsString());
//Смотрим как залочено приложение!!
if (!UserLocal.getInstance().getAppPassword().isEmpty()) {
//Лок по паролю
PinCodeActivity.dataManagerListener = new DataManager.DataManagerListener<String>() {
@Override
public void dataReady(String data) {
if (data != null) {
//Типо все успешно - зашли
NetClient.mainPost(sendJson);
} else {
RXData.contextBehaviorRelay.accept(MainActivity.this);
InstrumentsAlert.getInstance().showDialogOneButton(
"подтверждение операции",
"Вы отменили подтверждение перации.",
"Да",
null);
}
}
};
openActivity(PinCodeActivity.class);
} else {
//лок по пальцу
InstrumentsBiometric.init(MainActivity.this);
InstrumentsBiometric.getInstrumentsBiometric().checkBiometric(new DataManager.DataManagerListener<Boolean>() {
@Override
public void dataReady(Boolean data) {
if (data) {
//Типо все успешно - зашли
NetClient.mainPost(sendJson);
}
}
});
}
} else {
final List<Account> accountList = new ArrayList<>();
//Предлагаем список аккаунтов
List<String> stringList = new ArrayList<>();
for (Account acc : user.getAccounts()) {
if (!acc.get__type().equals("userBonusAccount")) {
stringList.add("Тип - " + acc.get__type() + " название - " + acc.getBalance());
accountList.add(acc);
}
}
InstrumentsAlert.getInstance().showDialogList("Выберите счет", stringList, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//Какой счет выбрали
final JsonObject sendJson = new JsonObject();
sendJson.addProperty("router", "confirmOperation");
sendJson.addProperty("senderAccountHashId", accountList.get(which).getHashId());
sendJson.addProperty("operationHashId", mySocketEvent.getAsObject().get("operationId").getAsString());
//Смотрим как залочено приложение!!
if (!UserLocal.getInstance().getAppPassword().isEmpty()) {
//залочено по паролю
PinCodeActivity.dataManagerListener = new DataManager.DataManagerListener<String>() {
@Override
public void dataReady(String data) {
if (data != null) {
//Типо все успешно - зашли
NetClient.mainPost(sendJson);
} else {
RXData.contextBehaviorRelay.accept(MainActivity.this);
InstrumentsAlert.getInstance().showDialogOneButton(
"подтверждение операции",
"Вы отменили подтверждение перации.",
"Да",
null);
}
}
};
openActivity(PinCodeActivity.class);
} else {
//Залочено биометрией!
InstrumentsBiometric.init(MainActivity.this);
InstrumentsBiometric.getInstrumentsBiometric().checkBiometric(new DataManager.DataManagerListener<Boolean>() {
@Override
public void dataReady(Boolean data) {
if (data) {
//Типо все успешно - зашли
NetClient.mainPost(sendJson);
}
}
});
}
}
});
}
}
});
break;
}
case operationComplete: {
DataManager.getInstance().cacheData(null);
NetClient.handShake(null);
String text = mySocketEvent.getAsObject().get("message").getAsString();
InstrumentsAlert.getInstance().showImageAlert(
InstrumentsAlert.AlertTypesEnum.OperationSuccess,
text,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
break;
}
case newMessage: {
if (mySocketEvent.getAsObject().get("error") != null) {
HyperLog.d(LOG, "пришла ошибка приемного сообщения");
InstrumentsAlert.getInstance().showDialogError("Пришла ошибка с сервера " + mySocketEvent.getAsObject(), null);
} else {
HyperLog.d(LOG, "С сообщением все ок!! " + mySocketEvent.getAsObject());
Msg msg = DataManager.getInstance().parseMsg(mySocketEvent.getAsObject());
RXData.newMsgRelay.accept(msg);
//Чтобы у меня сразу перешел диалог на того оператора который мне написал!
UserLocal.getInstance().setOperatorHashId(msg.getOperatorHashId());
}
break;
}
case sameUserConnected: {
InstrumentsAlert.getInstance().showAppExitDialog();
break;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment