HOME FORUMS MEMBERS RECENT POSTS LOG IN  
× Авторизация
Имя пользователя:
Пароль:
Нет аккаунта? Регистрация
Баннер 1   Баннер 2
НОВЫЕ ТОРГОВАЯ НОВОСТИ ЧАТ
loading...
Скрыть
Вернуться   ANTICHAT > ПРОГРАММИРОВАНИЕ > Общие вопросы программирования
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

  #1  
Старый 30.01.2017, 04:29
gattsu
Участник форума
Регистрация: 24.11.2015
Сообщений: 165
С нами: 5509192

Репутация: 1457
По умолчанию

Нашел более менее оптимальный вариант, проектирование систем на основе акторов, в java.

Для простоты и прозрачности, логики, все поведение програмируется внутренними классами.

Реализовал базовый набор по Hewitt-у, во время обработки сообщения, актор может:

- отправлять сообщения другим акторам и самому себе(рекурсивное сообщение) (метод Context.send и Reference.send)

- менять свое поведения (метод Context.become)

- создавать других акторов (метод Context.create)

О поведении актора, на основе просто примере будет более наглядно:

Цитата:
Сообщение от Спойлер  


Код:


Код:
package fact.samples;

import fact.Context;

public class Account implements Context {
    final String login;
   
    final String password;
   
    Account(String login, String password) {
        this.login = login;
        this.password = password;
    }
   
    public void define() {
        become("Free");
    }
   
    public void logout() {
        System.out.println("wrong logout");
    }
   
    public class Free {
       
        public void login(String login, String password) {
            if(Account.this.login.equals(login) && Account.this.password.equals(password)) {
                System.out.println("login success");
                become("Login");
            } else
                System.out.println("wrong login or password");
        }
       
    }
   
    public class Login {
       
        public void login(String login, String password) {
            System.out.println("account in use");
        }
       
        public void logout() {
            System.out.println("logout");
            become("Free");
        }
    }
}
В данном коде, есть актор Account, у которого, есть два поведения(внутренних класса) Free и Login. У каждого из них есть, свои обработчики сообщений.

Если расширить данный пример, можно реализовать актор для сервера авторизации.

Замечание: если пришло сообщение, которого нету в заданном поведение, то метод для обработки сообщения ищеться в базов классе. В данном примере, если отправить сообщение logout, когда актор установлен как Free, будет вызван обработчик из базового класса Account, на экран консоли, выведиться сообщение "wrong logout"

Пример использования:

Цитата:
Сообщение от Спойлер  


Код:


Код:
package fact.samples;

import fact.Context;
import fact.Model;
import fact.Reference;

public class AccountSample implements Context {

    public void define() {
        Reference account = create("account", new Account("root", "root"));
        account.send("logout");
        account.send("login", "root", "1243");
        account.send("login", "root", "root");
        account.send("login", "root", "root");
        account.send("logout");
        account.send("logout");
        account.send("login", "root", "root");
    }
   
    public static void main(String...args) {
        Model.launch(new AccountSample());
    }
   
}
console output:

Код:


Код:
wrong logout
wrong login or password
login success
account in use
logout
wrong logout
login success
 
Ответить с цитированием

  #2  
Старый 30.01.2017, 08:50
gattsu
Участник форума
Регистрация: 24.11.2015
Сообщений: 165
С нами: 5509192

Репутация: 1457
По умолчанию

- Добавил отправку сообщений с задержкой

Цитата:
Сообщение от Спойлер  


Код:


Код:
package fact.samples;
import fact.Context;
import fact.Model;
public class CounterDelay implements Context {
    private long count = 0;
   
    public void define() {
        send("print").delay(1000);
        send("tick");
    }
   
    public void tick() {
        count++;
        send("tick");
    }
   
    public void print() {
        System.out.println(count);
        count = 0;
        send("print").delay(1000);
    }
   
    public static void main(String...args) {
        Model.launch(new CounterDelay());
    }
}
В данном примере, актор отправляет себе два сообщение:

- print с задержкой 1сек

- tick без задержок

оба сообщения рекурсивны. На каждое сообщения tick, увеличивается счетчик, на каждое сообщения print отображается показатель счетчика и затем сбрасывается на ноль.

Заложил сетевой фреймворм, на основеjava.nio.

Для простого примера реализавал, ехо сервер.
 
Ответить с цитированием

  #3  
Старый 01.02.2017, 21:05
gattsu
Участник форума
Регистрация: 24.11.2015
Сообщений: 165
С нами: 5509192

Репутация: 1457
По умолчанию

Обновил. "немного" переделал код. Интерфейс остался обратно совместимый. Исключение запросы.

- добавил полный цикл обслуживания актора create/stop/resume/terminate(kill).

При остановке, возврате или удаленния актора, можно устанавливать,обратный вызов, функция которая будет вызвана, в случае успешной операции.

Примечани: Функции обратного вызова должны быть определенны в классе актора.
 
Ответить с цитированием

  #4  
Старый 01.02.2017, 21:33
gattsu
Участник форума
Регистрация: 24.11.2015
Сообщений: 165
С нами: 5509192

Репутация: 1457
По умолчанию

Управление запросами

Для запрос к другому актору, нужно объявить класс-поведение, и задать методы с возможной сигнатурой ответа. При вызове метода request, возвращается объект Future, в котором черем метод handle, нужно указать имя поведения, для обработки ответа.

Внимание: если не указать поведение, то запрсов не выполниться.

При ответе, актор может получить сообщения типа reply или complaint, в классе-поведения обрабатывающий запрос, нужно покрыть возможные варианты сигнатуры сообщения.

Пример:

Есть актор Account, в котором присутсвует медот-обработчик login. При обработке сообщения, если данные логина и пароля, соответсвует данным аккаунта, то Account отправляет объект LoginSuccess, если не правильные данные, то отвечает через метод complaint, отправляет LoginFail.WrongLoginOrPassword.

Цитата:
Сообщение от Спойлер  


Код:


Код:
package fact.samples;

import fact.Context;

public class AccountRequest implements Context {
    private String login;
   
    private String password;
   
    public AccountRequest(String login, String password) {
        this.login = login;
        this.password = password;
    }
   
    public void login(String login, String password) {
        if(this.login.equals(login) && this.password.equals(password)) {
            reply(success);
        } else
            complaint(LoginFail.WrongLoginOrPassword);
    }
   
    public static class LoginSuccess {
        private LoginSuccess() { }
    }
   
    private final static LoginSuccess success = new LoginSuccess();
   
    public enum LoginFail {
        WrongLoginOrPassword,
        AccountInUse
    }
}
В акторе который производит запрос, присутсвует класс поведения Request, в котором определенны два обработчика, на успешный запрос и провальный запрос. Для простоты, создаем актор-аккаунт, на месте.

В примере показывается, что вовремя запроса, актор будет обрабатывать, только ответ. Другие сообщения обрабатываются после запроса, то есть актор блогируется для обработки входящих сообщения, за исключение ответа на запрос.

Цитата:
Сообщение от Спойлер  


Код:


Код:
public class RequestSample implements Context {
    Reference account;
   
    public void define() {
        account = create("account", new AccountRequest("root", "root"));
        account.request("login", "login", "login").handle("Request");
        send("tick");
        send("print");
    }
   
    public void tick() {
        account.request("login", "root", "root").handle("Request");
        send("print");
    }
   
    public void print() {
        System.out.println("print");
    }
   
    public class Request {
       
        public void reply(LoginFail fail) {
            System.out.println("login failed");
        }
       
        public void reply(LoginSuccess success) {
            System.out.println("login success");
        }
    }
   
    public static void main(String...args) {
        Model.launch(new RequestSample());
    }
}
История вычислений данного примера:

[QUOTE="Спойлер"]
[COLOR="#363940"]
0 E AccountRequest
 
Ответить с цитированием

  #5  
Старый 02.02.2017, 01:22
gattsu
Участник форума
Регистрация: 24.11.2015
Сообщений: 165
С нами: 5509192

Репутация: 1457
По умолчанию

- Переделал сетвой API. Реализовал пример эхо сервера.( Соединение отправляет каждые 100 мс строку, сервер читает её отображает на консоль и отправляет обратно, клиент читае и отображает на консоль)

- Переместил сетевой API в репозиторий ядра.

- Добавил методы для определения типа сообщения(запрос, ответ, ответ-ошибка)
 
Ответить с цитированием

  #6  
Старый 02.02.2017, 12:34
gattsu
Участник форума
Регистрация: 24.11.2015
Сообщений: 165
С нами: 5509192

Репутация: 1457
По умолчанию

Обновил:

- реализовал цепочку запросов

- реализовал передачу запрос(continuation)

- реализовал управляющие методы статическим путем, объявленны в fact.ActorContext. Теперь можно получить доступ к управляющим метода чере import static

Добавил соответствующие примеры
 
Ответить с цитированием

  #7  
Старый 02.02.2017, 23:00
gattsu
Участник форума
Регистрация: 24.11.2015
Сообщений: 165
С нами: 5509192

Репутация: 1457
По умолчанию

Исправиль некоторые ошибки.

Немного lineage. Написал каркас для сервера авторизации.(interlude)

Нужно организовать

- работу с базой данных

- работу с игровыми серверами. Написать, proxy для игрового сервера.

- переписать сетевую библиотеку, организовать чтение по требованию.

ПС: Для меня не понятно, каким образом работает реализация, криптографии, добавление контрольной суммы и шифровка первого пакет xor ключем. Отсутвует

смешение, для задания предела, самое интересное, если подать буффер в котором, уже записанно, минимум 4 байта, то криптография накроется медным тазом. У меня закрались дикие сомнения, что реализация на l2j, если её топорным путем перенести на С не будет работать, так как в jvm зануляет все значения в созданных массивах. Понятно, что в сервере авторизаии, может быть только один пакен на запись и один на чтение, по протоколу, но это всеравно не делает менее ужасней эту криптографию.

Не могу понять почему выдает ошибку контрольной суммы, переодически... магия...

ПС Двойная авторизация, в l2j вообще кабздец, как так можно было сделать. Ошибка, котороя тянется на все сборки
 
Ответить с цитированием

  #8  
Старый 02.02.2017, 23:30
Attme
Участник форума
Регистрация: 01.02.2017
Сообщений: 210
С нами: 4882736

Репутация: 0
По умолчанию

[OFF]Тема одного актёра?[/OFF]
 
Ответить с цитированием

  #9  
Старый 02.02.2017, 23:39
6yka
Познавший АНТИЧАТ
Регистрация: 07.11.2015
Сообщений: 1,730
С нами: 5534362

Репутация: 1617


По умолчанию

[OFF]

Цитата:
Сообщение от Attme  

[OFF]Тема одного актёра?[/OFF]
а ты присоединись [/OFF]
 
Ответить с цитированием

  #10  
Старый 02.02.2017, 23:45
kick
Флудер
Регистрация: 20.01.2015
Сообщений: 7,201
С нами: 5952720

Репутация: 6527


По умолчанию

Цитата:
Сообщение от Attme  

[OFF]Тема одного актёра?[/OFF]
Человек описывает свою работу, не нравится внесите свою лепту
 
Ответить с цитированием
Ответ





Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT ™ © 2001- Antichat Kft.

×

Внести депозит

Введите сумму USDT:

Принимается только USDT TRC20. Fake/Flash USDT не засчитывается.

×

Вывести депозит

Сумма USDT:

Ваш USDT TRC20 кошелек:

Заявка будет отправлена администратору.