ANTICHAT

ANTICHAT (https://forum.antichat.xyz/index.php)
-   Общие вопросы программирования (https://forum.antichat.xyz/forumdisplay.php?f=206)
-   -   актор 0.* (https://forum.antichat.xyz/showthread.php?t=767782)

gattsu 30.01.2017 04:29

Нашел более менее оптимальный вариант, проектирование систем на основе акторов, в 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



gattsu 30.01.2017 08:50

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

Цитата:

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


Код:


Код:

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.

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

gattsu 01.02.2017 21:05

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

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

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

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

gattsu 01.02.2017 21:33

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

Для запрос к другому актору, нужно объявить класс-поведение, и задать методы с возможной сигнатурой ответа. При вызове метода 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

gattsu 02.02.2017 01:22

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

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

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

gattsu 02.02.2017 12:34

Обновил:

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

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

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

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

gattsu 02.02.2017 23:00

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

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

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

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

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

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

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

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

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

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

Attme 02.02.2017 23:30

[OFF]Тема одного актёра?[/OFF]

6yka 02.02.2017 23:39

[OFF]

Цитата:

Сообщение от Attme

[OFF]Тема одного актёра?[/OFF]

а ты присоединись [/OFF]

kick 02.02.2017 23:45

Цитата:

Сообщение от Attme

[OFF]Тема одного актёра?[/OFF]

Человек описывает свою работу, не нравится внесите свою лепту


Время: 18:31