Вопрос

У меня есть веб -приложение Django. У меня также есть сервер заклинаний, написанный с использованием Twisted, работающего на той же машине с Django (работа localhost:8090) Идея состоит в том, что когда пользователь делает какое -то действие, запрос приходит в Django, которая, в свою очередь, подключается к этому искаженному серверу и серверу отправляет данные обратно в Django. Наконец, Django помещает эти данные в какой -то шаблон HTML и обслуживает их обратно пользователю.

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

...
        factory = Spell_Factory(query) 
        reactor.connectTCP(AS_SERVER_HOST, AS_SERVER_PORT, factory)
        reactor.run(installSignalHandlers=0)
        print factory.results
...

А reactor.run() вызывает проблему. Так как это цикл событий. В следующий раз, когда этот же код будет выполнен Джанго, я не могу подключиться к серверу. Как с этим справиться?

Это было полезно?

Решение

Приведенные выше два ответа верны. Однако, учитывая, что вы уже реализовали правописание сервер тогда запустить это как один. Анкет Вы можете начать с запуска на той же машине, что и отдельный процесс - при localhost:PORT. Анкет Прямо сейчас кажется, что у вас уже есть очень простой интерфейс двоичного протокола - вы можете реализовать столь же простой клиент Python, используя стандартные LIB socket Интерфейс в режиме блокировки.

Однако я предлагаю поиграть с twisted.web и разоблачить простой веб -интерфейс. Вы можете использовать JSON для сериализации и десериализации данных, которые хорошо поддерживаются Django. Вот очень быстрый пример:

import json
from twisted.web import server, resource
from twisted.python import log

class Root(resource.Resource):
    def getChild(self, path, request):
        # represents / on your web interface
        return self

class WebInterface(resource.Resource):
    isLeaf = True
    def render_GET(self, request):
        log.msg('GOT a GET request.')
        # read request.args if you need to process query args
        # ... call some internal service and get output ...
        return json.dumps(output)

class SpellingSite(server.Site):
    def __init__(self, *args, **kwargs):
        self.root = Root()
        server.Site.__init__(self, self.root, **kwargs)
        self.root.putChild('spell', WebInterface())

И для его запуска вы можете использовать следующий скелет .tac файл:

from twisted.application import service, internet

site = SpellingSite()
application = service.Application('WebSpell')
# attach the service to its parent application
service_collection = service.IServiceCollection(application)
internet.TCPServer(PORT, site).setServiceParent(service_collection)

Запуск вашего сервиса в качестве еще одного первого класса службы позволяет запустить его на другой машине однажды, если вы найдете необходимость - выявление веб -интерфейса позволяет легко горизонтально масштабировать его за обратным балансировщиком нагрузки.

Другие советы

reactor.run() следует вызывать только один раз во всей вашей программе. Не думайте об этом как «Начни эту единственную просьбу, которую я имею», думайте об этом как «Начни все извращенные».

Запуск реактора в фоновой нити - один из способов обойти это; тогда ваше приложение Django может использовать blockingCallFromThread В вашем приложении Django и используйте скрученный API, как и в любом блокирующем API. Вам понадобится небольшое сотрудничество в вашем контейнере WSGI, потому что вам нужно будет убедиться, что этот фона скрученной поток запускается и останавливается в подходящее время (когда ваш интерпретатор инициализируется и разорван соответственно).

Вы также можете использовать Twisted в качестве контейнера WSGI, а затем вам не нужно начинать или останавливать что -либо особенное; blockingCallFromThread Будет сразу же работать. Смотрите помощь командной линии для twistd web --wsgi.

Вы должны остановить реактор после получения результатов от Twisted Server или какой -то ошибки/тайм -аут. Таким образом, по каждому запросу Django, который требует запроса вашего видно сервера, вы должны запустить реактор, а затем остановить его. Но это не поддерживается Twisted Library - реактор не является перезапущенным. Возможные решения:

  • Используйте отдельный поток для Twisted Reactor, но вам нужно будет развернуть ваше приложение Django с сервером, которое имеет поддержку для долгого хода потоков (я сейчас не имею ни одного из них, но вы можете легко написать свой собственный :-)).

  • Не используйте Twisted для реализации клиентского протокола, просто используйте простые stdlib socket модуль.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top