LINUX.ORG.RU

простой сервер на лиспе


0

2

Здравствуйте!
Имеется лисп и клиенты (на самом деле на Дельфи, но будем считать, что они будут на питоне или чем-нибудь ещё). Задача - сделать систему клиент/сервер:
- обмен между клиентом и сервером - по tcp/ip (сокеты?)
- ведение списка пользователей
- авторизация с паролем
- возможность шифрования
- каждый клиентский процесс - это отдельный thread на сервере в рамках единого образа лиспа
- общение происходит синхронно. Инициатива в общении принадлежит клиенту. С точки зрения приложения, клиент отправляет запрос (несколько строк, затем признак завершения запроса, либо sexp) и ждёт строки результата (несколько строк, затем признак завершения, либо sexp, либо что-то ещё с однозначным признаком завершения).
- определение того, что клиент ещё не умер, если умер - вызов ф-ии на стороне лиспа для корректного закрытия соединения
- таймаут на клиенте.
- клиент должен иметь возможность корректно отработать обрыв связи.
Производительность не имеет большого значения.

Прошу совета, в какую сторону копать, а ещё лучше - где взять образец кода для раздраконивания/перепиливания. Например, годится ли telnet и есть ли у него вменяемая реализация на лиспе? slime, видимо, не годится, т.к. отсутствует авторизация, а клиент - только лисповый. Можно было бы сделать через веб-сервер, но он асинхронный да и вообще это извращение.

★★★★★

Ответ на: комментарий от shty

Молодец (для уровня 1-го класса начальной школы).

Давай-ка ты это, вернись-ка к теме, окей? А то скучно как-то.

anonymous
()

я бы выкинул лисп, и юзал питон pyro|rpyc|twisted на клиенте и сервере в зависимости от ситуации.

конечно если лисп самоцель, то да

redixin ★★★★
()
Ответ на: комментарий от den73

А можете ещё объяснить необразованному, если у меня по треду на коннект, я могу на это полагаться и хранить контекст просто в виде переменных треда или в виде стека треда? Или я должен хранить состояние явно и в любой запрос добавлять код сессии?

И ещё вопросы. 1. Есть такое понятие, как keepalive. Могу ли я полагаться на него, чтобы коннект длился так долго, как мне надо? Или это зависит не от hunchentoot, а от сервера? 2. Навскидку, легко ли мне будет сделать такую вещь, как eval заданного выражения с клиента в контексте соединения? По идее не вижу проблем...

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

А можете ещё объяснить необразованному, если у меня по треду на коннект, я могу на это полагаться и хранить контекст просто в виде переменных треда или в виде стека треда?

Конечно можешь.

Могу ли я полагаться на него, чтобы коннект длился так долго, как мне надо?

Нет, полагаться не стоит, но можно надеяться, что таймауты на неактивное соединение в стэке ОС не истекут и соединение не будет закрыто, как неактивное (неактивность, ИМНИП, измеряется минутами, что-то близко к 15мин по умолчанию).

Навскидку, легко ли мне будет сделать такую вещь, как eval заданного выражения с клиента в контексте соединения? По идее не вижу проблем...

Если будешь учитывать разное окружение — проблем не будет.

anonymous
()
Ответ на: комментарий от anonymous

Сразу замечание: это у тебя «real work» такой, что ничего не требует. Не стоит обобщать.

не у меня, а у ТС:

Производительность не имеет большого значения.

Слушай, ты хоть каким-нибудь языком владеешь (хотя бы на среднем уровне)? Английский, пайтон, русский — везде у тебя ошибки.

сильное заявление, особенно от того кто не умеет читать :)

shty ★★★★★
()
Ответ на: комментарий от redixin

Питон приведён _для_примера_. Я не собираюсь им пользоваться. Так чт о пропаганда здесь не в тему.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

А можете ещё объяснить необразованному, если у меня по треду на коннект, я могу на это полагаться и хранить контекст просто в виде переменных треда или в виде стека треда?

Да.

И ещё вопросы. 1. Есть такое понятие, как keepalive. Могу ли я полагаться на него, чтобы коннект длился так долго, как мне надо?

Да. Но сетевые соединения ненадёжны по своей природе, так что обработка аварийных ситуаций - это маст хэв в любом случае.

2. Навскидку, легко ли мне будет сделать такую вещь, как eval заданного выражения с клиента в контексте соединения? По идее не вижу проблем...

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

mv ★★★★★
()
Ответ на: комментарий от anonymous

Молодец (для уровня 1-го класса начальной школы).

Давай-ка ты это, вернись-ка к теме, окей?

ты даже такой уровень не осилил, куда там возвращаться?

А то скучно как-то.

пёрни и понюхай, раз совсем нечем себя занять - тренируй рецепторы

shty ★★★★★
()
Ответ на: комментарий от anonymous

Нет, полагаться не стоит, но можно надеяться, что таймауты на неактивное соединение в стэке ОС не истекут и соединение не будет закрыто, как неактивное (неактивность, ИМНИП, измеряется минутами, что-то близко к 15мин по умолчанию)

Ладно, примерно понял, спасибо. hunchentoot поставил, пример по авторизации где-то валялся. Видимо, тему можно закрывать.

den73 ★★★★★
() автор топика
Ответ на: комментарий от mv

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

Наглая, ничем не прикрытая ложь. Я был о тебе лучшего мнения. Да, надо тебя сжечь с позиции ЦТО! ж)

anonymous
()
Ответ на: комментарий от anonymous

Аргументы, сестра, аргументы!

раз уж есть вариант клиента на питоне, то почему не юзать его и на сервере, и не использовать проверенные средства которые идеально подходят под задачу?

redixin ★★★★
()
Ответ на: комментарий от den73

Питон приведён _для_примера_.

Ясно. Тогда не забудь отписаться о результатах, а именно о применимости лиспа в такой вот задаче на практике.

redixin ★★★★
()
Ответ на: комментарий от anonymous

Уже есть клиенты на хаскеле,

раз уж есть вариант клиента на питоне

Уроки чтения на ЛОРе.

redixin ★★★★
()
Ответ на: комментарий от den73

Ну это понятно, просто интересно с чем пришлось туго, а что пошло как по маслу.

redixin ★★★★
()
Ответ на: комментарий от den73

А можете ещё объяснить необразованному, если у меня по треду на коннект, я могу на это полагаться и хранить контекст просто в виде переменных треда или в виде стека треда? Или я должен хранить состояние явно и в любой запрос добавлять код сессии?
1. Есть такое понятие, как keepalive. Могу ли я полагаться на него, чтобы коннект длился так долго, как мне надо?

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

Для keepalive либо химичить с poll-ингом либо лежащий рядом Hunchensocket c websockets (штука новая я не пробовал) но вот как c этими web-сокетами на делфях и питоне это вопрос.

2. Возможно конечно, но на мой вкус стремно by desigan. Протокол или независимый и тогда web-овские post и query. Или завязан на конкретную свзку клиент-сервер и тогда определяем внутеря команды и транслирум на транспортный уровень без собирания на делфях s-exp-ов (утрировано).

antares0 ★★★★
()
Ответ на: комментарий от anonymous

Наглая, ничем не прикрытая ложь.

Аргументы?

Я был о тебе лучшего мнения.

Меня не волнует ничьё мнение, кроме нескольких уважаемых мною людей. Мнение анонимуса точно не волнует.

mv ★★★★★
()

Что-то я не понял, разве не достаточно будет man sockets, ssl, sqlite?

Tark ★★
()

простой сервер на лиспе

Ты же LispWorks(R) используешь, не так ли?

В пакете COMM есть все для этого, включая SSL.

gensym ★★
()
Ответ на: комментарий от gensym

В пакете COMM есть все для этого, включая SSL

Да, я это уже нашёл по наводке mv. Нужно ещё авторизацию докрутить руками. Но я теперь думаю, что hunchentoot тоже имеет смысл, т.к. позволяет делать веб-морду. В общем, буду думать, на сегодня острая надобность пока отпала, подготовительные действия проделал, теперь, видимо, до следующего раза.

den73 ★★★★★
() автор топика
Ответ на: комментарий от vasily_pupkin

Это не фу, это XXI век

Разве что в каком-то параллельном измерении.

archimag ★★★
()
Ответ на: комментарий от mv

Только выражение должно быть самодостаточным, т.е. не тянуть локальные зависимости.

Это требование можно дропнуть, но непортабельным образом. Есть реализация для SCBL, если интересно, могу заделиться.

anonymous
()
Ответ на: комментарий от anonymous

Это требование можно дропнуть, но непортабельным образом. Есть реализация для SCBL, если интересно, могу заделиться.

Интересно.

mv ★★★★★
()
Ответ на: комментарий от mv

> > > Только выражение должно быть самодостаточным, т.е. не тянуть локальные зависимости.

> > Наглая, ничем не прикрытая ложь.

> Аргументы?

Подумай же. Что плохого в «локальных зависимостях», если 1) окружения одинаковые (банально) 2) мы протастиваем окружение

Меня не волнует ничьё мнение, кроме нескольких уважаемых мною людей. Мнение анонимуса точно не волнует.

И что дальше-то?

anonymous
()
Ответ на: комментарий от anonymous

Подумай же. Что плохого в «локальных зависимостях», если 1) окружения одинаковые (банально)

Это не локальная зависимость, а униформное окружение. Читай Таненбаума.

2) мы протастиваем окружение

В CL нет стандартных средств для интроспекции окружения. Зато есть несериализуемые объекты, которые через REPL не протащить.

mv ★★★★★
()
Ответ на: комментарий от antares0

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

Ты что курил??

Для keepalive либо химичить с poll-ингом либо лежащий рядом Hunchensocket c websockets (штука новая я не пробовал) но вот как c этими web-сокетами на делфях и питоне это вопрос.

Ыррр. Бред. man setsockopt.

Web-сокет — это что такое?

2. Возможно конечно, но на мой вкус стремно by desigan.

тремно by desigan.

Меня сейчас вырвет от такого концентрированного потока продуктов твоей жизнидеятельности.

anonymous
()
Ответ на: комментарий от mv

> Подумай же. Что плохого в «локальных зависимостях», если 1) окружения одинаковые (банально)

Это не локальная зависимость, а униформное окружение. Читай Таненбаума.

Нам не нужно униформное окружение. Нам не нужно в принудительном порядке синхронизировать энвайронмент. Исполнять удалённо код можно и так, если учитывать разные окружения (включая локальные состояния)

Про «локальную завимость» не ясно. Можешь подробнее? Это похоже на неформальное термин, нет?

anonymous
()
Ответ на: комментарий от mv

> 2. Навскидку, легко ли мне будет сделать такую вещь, как eval заданного выражения с клиента в контексте соединения? По идее не вижу проблем...

Только выражение должно быть самодостаточным, т.е. не тянуть локальные зависимости.

«Локальные зависимости» - это локальные по отношению к среде исполнения? С какой стати их нельзя «тянуть»?

anonymous
()
Ответ на: комментарий от anonymous

«Локальные зависимости» - это локальные по отношению к среде исполнения? С какой стати их нельзя «тянуть»?

Если их можешь вытянуть - пожалуйста. В чём твой вопрос-то?

mv ★★★★★
()
Ответ на: комментарий от anonymous

Если выполнение некого кода зависит от его контекста, то порой задолбёшься весь этот контекст из точки А до точки Б по сети гонять)

yoghurt ★★★★★
()
Ответ на: комментарий от mv

Это требование можно дропнуть, но непортабельным образом. Есть реализация для SCBL, если интересно, могу заделиться.

Интересно.

; SB-INT:EVAL-IN-LEXENV does not pay attention to lexical variables. For
; example the following code
; (macrolet ((env (&environment) env))
;   (let ((x 42))
;     (sb-int:eval-in-lexenv 'x (env))))
; will raise UNBOUND-VARIABLE error. This is because
; SB-INT:SIMPLE-EVAL-IN-LEXENV uses SYMBOL-VALUE to obtain value of the
; variable. There seems to be no easy way to get the correct value in
; SB-INT:SIMPLE-EVAL-IN-LEXENV (env parameter can't provide variable value).
; However, there is a workaround.  EVAL-IN-LEXENV macro declared below expands
; to a code that captures _all_ visible lexical variables, functions and macros
; and sneaks them into the null lexical environment established by EVAL
; function. 
;
; Transformation technique:
; variables:
; (let ((x ...))
;   (flet ((#:x (&optional (#:value nil #:value-set))
;            (if #:value-set
;              (setf x #:value)
;              x)))
;     (eval
;       `(flet ((x ()    (funcall (function ,#:x)))
;               (setf x) (#:value) (funcall (function ,#:x #:value)))
;          (symbol-macrolet ((x (x)))
;            ,exp)))))
; functions:
; (flet ((f (arg) ...))
;   (eval
;     `(flet ((#:f (&rest args) (apply ,#'f args)))
;        ,exp)))
; macros:
; (macrolet ((m (arg) ...))
;   (eval
;     `(macrolet ((m (&whole w &environment e) 
;                   (apply ,(macro-function 'm env) w e)))
;        ,exp)))

; TODO: seek the opportunity to override lexical function and macro definitions
; with equivalents of defun and defmacro
(defmacro eval-in-lexenv (exp &environment env)
  "Like EVAL, but works in lexical environment"
  (let (varrefs refvars symbol-macrolets funs macros)
    (let ((value     (gensym "VALUE"))
          (value-set (gensym "VALUE-SET")))
      (dolist (v (sb-c::lexenv-vars env))
        (unless (typep (cdr v) 'sb-c::global-var)
          (let* ((var (car v))
                 (ref (gensym (symbol-name var))))
            ; Use ref instead of var to avoid possible clashes with macro and
            ; function names (when a function or a macro and a variable share
            ; one name in the calling environment)
            (push `(,ref (&optional (,value nil ,value-set)) 
                     (if ,value-set
                       (setf ,var ,value)
                       ,var))
                  varrefs)
            (push ``(,',ref () (funcall ,(function ,ref)))
                  refvars)
            (push ``((setf ,',ref) (,',value) (funcall ,(function ,ref) ,',value))
                  refvars)
            (push `(,var (,ref)) 
                  symbol-macrolets))))
      (dolist (f (sb-c::lexenv-funs env))
        (let* ((fun (car f)))
          (if (listp (cdr f))
            (progn
              (assert (eq (cadr f) 'sb-sys:macro) ()
                "eval-in-lexenv: unexpected lexical function type ~a, ~
                 expected 'sb-sys:macro in cadr"
                 f)
              (push ``(,',fun (&whole whole &environment environment)
                        (funcall ,,(macro-function fun env) whole environment))
                    macros))
            (push ``(,',fun (&rest ,',value) (apply ,(function ,fun) ,',value))
                  funs)))))
    `(flet ,varrefs
       (eval
         `(macrolet ,(list ,@macros)
            (flet ,(list ,@refvars ,@funs)
              (symbol-macrolet ,',symbol-macrolets
                ,,exp)))))))
anonymous
()
Ответ на: комментарий от mv

В чём твой вопрос-то?

Вопрос видимо был в том, что ты неявно подразумевал необходимость «униформного» окружения.

Для удалённого выполнения кода это абсолютно ненужно.

anonymous
()
Ответ на: комментарий от den73

нда, глупо я сделал, задав такой вопрос анонимусу, который является неопределённым кругом лиц. Выход только один: в этой теме я больше не общаюсь с анонимусом.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Приношу анонимусу извинения.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Добавить в клиент на дельфи обработчик команд от сервера.
«Если пакет такой то, то открыть диалоговое окно"mc.

anonymous
()

можешь посмотреть PicoLisp http://software-lab.de/doc/app.html http://picolisp.com http://www.prodevtips.com/2008/03/28/pico-lisp/

или «система на лиспе» уже рабочая и ты хочешь к ней прикрутить веб-интерфейс?

если хочется телнета, то можно посмотреть например MUDы на лиспе: http://common-lisp.net/project/lmud/ http://sourceforge.net/projects/bmud , а потом завернуть это в какой-нибудь ssh

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.