У меня работает витой реактор, как к нему подключиться?

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

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

Редактировать:

Это сценарий сервера:

import time
import multiprocessing

from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor

class TTT(LineReceiver):
    def __init__(self, users):
        self.users = users
        self.name = None
        self.state = "GETNAME"

    def connectionMade(self):
        self.sendLine("You are connected")

    def connectionLost(self, reason):
        if self.users.has_key(self.name):
            del self.users[self.name]

    def lineReceived(self, line):
        if line == "quit":
            reactor.stop()

        if self.state == "GETNAME":
            self.handle_GETNAME(line)
        else:
            self.handle_CHAT(line)

    def handle_GETNAME(self, name):
        if self.users.has_key(name):
            self.sendLine("Name taken, please choose another.")
            return
        self.sendLine("Welcome, %s!" % (name,))
        self.name = name
        self.users[name] = self
        self.state = "CHAT"

    def handle_CHAT(self, message):
        message = "<%s> %s" % (self.name, message)
        for name, protocol in self.users.iteritems():
            if protocol != self:
                protocol.sendLine(message)


class TTTFactory(Factory):
    def __init__(self):
        self.state = [0 for x in range(9)]
        self.turn = -1

        self.users = {} # maps user names to Chat instances

    def make_move(self, player, x, y):
        if player != self.turn:
            return "Not your turn"

        i = x + y * 3

        if self.state[i] != 0:
            return "Invalid move"

        self.state[i] = player

        # Horrizontal
        if self.state[0] == self.state[1] == self.state[2]: return "Win"
        if self.state[3] == self.state[4] == self.state[5]: return "Win"
        if self.state[6] == self.state[7] == self.state[8]: return "Win"

        # Vertical
        if self.state[0] == self.state[3] == self.state[6]: return "Win"
        if self.state[1] == self.state[4] == self.state[7]: return "Win"
        if self.state[2] == self.state[5] == self.state[8]: return "Win"

        # Diagonal
        if self.state[0] == self.state[4] == self.state[8]: return "Win"
        if self.state[6] == self.state[4] == self.state[2]: return "Win"

        # Swap turn
        self.turn = 0 - self.turn
        return "Next move"

    def buildProtocol(self, addr):
        return TTT(self.users)

# def reactor_runner():
def new_server(conn):
    port_num = 8007
    conn.send(port_num)

    reactor.listenTCP(port_num, TTTFactory())
    reactor.run()

Я хочу, чтобы другая программа / процесс python отправляла и принимала сообщения от нее. Идея проекта - создать многопользовательскую игру в крестики-нолики.

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


person Teifion    schedule 04.12.2011    source источник
comment
Что вы имеете в виду под подключением к реактору?   -  person ypercubeᵀᴹ    schedule 05.12.2011
comment
что вы пытаетесь подключить к реактору? Можете ли вы показать нам, что у вас есть, а затем описать, что вы хотите делать дальше?   -  person SingleNegationElimination    schedule 05.12.2011
comment
github.com/Teifion/mp_tictactoe/blob/master/ttt_server.py - это сервер, который работает. Я хочу, чтобы другая программа могла отправлять и получать сообщения от нее. В целом проект задуман как игра в крестики-нолики (впоследствии я планирую перейти к стратегии в реальном времени).   -  person Teifion    schedule 05.12.2011
comment
Глядя на свой код, вы можете ошибаться в том, как работает реактор. Это одноэлементный объект, доступный из нескольких потоков. Нет одного реактора на сервер или чего-то подобного. Ваше приложение должно вызвать response.run () один раз, и любые вызовы таких методов, как response.listenTCP () после этого момента, вступят в силу немедленно.   -  person David K. Hess    schedule 05.12.2011
comment
Я понимаю эту часть, я пытаюсь сделать так, чтобы отдельные процессы (или программы в сети) могли получить доступ к одному и тому же реактору. Единственная причина, по которой все это в рамках одной программы, заключается в том, что хост запускает и клиентское, и серверное приложение (как я уже сказал, я новичок, если у вас есть лучшие идеи, меня искренне интересует).   -  person Teifion    schedule 05.12.2011
comment
Вы пытаетесь запустить twisted под многопроцессорностью? Лучше сначала запустить вашу скрученную деталь без многопроцессорной обработки   -  person number5    schedule 05.12.2011
comment
На данный момент да, но когда я добавляю 2-го игрока, должен быть совершенно другой процесс (даже другой компьютер) подключения. Я планировал написать это так, чтобы клиент и сервер были разделены.   -  person Teifion    schedule 05.12.2011
comment
Многопроцессорность только запутает вещи, так как будет означать, что у вас есть общий реактор, хотя на самом деле это не так. Это будут два разных реактора с двумя разными состояниями в двух разных процессах. Я считаю, что вам лучше с самого начала перейти на полностью отдельное клиентское приложение.   -  person David K. Hess    schedule 05.12.2011
comment
@Teifion: Вы говорите: Я пытаюсь сделать так, чтобы отдельные процессы (или программы в сети) могли получить доступ к одному и тому же реактору. Даже с вашей серверной программой сейчас вы можете иметь много программ, подключающихся к к вашему серверу (попробуйте с помощью telnet, откройте 2 или более программ telnet и подключитесь).   -  person ypercubeᵀᴹ    schedule 05.12.2011
comment
@ DavidK.Hess: Я не пытаюсь иметь более одного реактора, общего или какого-либо другого. Я пытаюсь заставить программу Python отправлять и получать сообщения с существующим реактором. Вопрос в том, есть ли у twisted что-то подобное или мне стоит использовать сокеты?   -  person Teifion    schedule 05.12.2011
comment
@ypercube: Да, я знаю, что у меня может быть несколько (у меня уже было 2 телнета). Я пытаюсь сделать так, чтобы программа Python заменила telnet при отправке информации. Не для имитации Telnet, а для того, чтобы быть клиентом в многопользовательской игре.   -  person Teifion    schedule 05.12.2011
comment
Итак, вам нужны Server.py и Client.py (у любого из них будет работать один реактор, но делать разные вещи). Сервер будет принимать соединения от многих клиентов, Клиент будет подключаться к (удаленному) Серверу. Сервер будет хранить список подключенных клиентов (пользователи, имена, выполненные действия и т. Д.).   -  person ypercubeᵀᴹ    schedule 05.12.2011
comment
@ypercube Реактор берет на себя весь поток, как мне заставить программу реагировать на ввод пользователя и обновлять графику, если у нее есть реактор?   -  person Teifion    schedule 05.12.2011
comment
Тогда ваш вопрос действительно таков: как объединить в программе пользовательский интерфейс (который использует X-?) И клиент (который использует Twisted)   -  person ypercubeᵀᴹ    schedule 05.12.2011
comment
@Teifion, похоже, вам нужно пойти и посмотреть примеры для ClientFactory. Вот как вы используете Twisted для написания клиентского приложения, которое может подключаться к вашей Factory. Что касается вашего вопроса по цепочке, есть некоторые сторонние реакторы (например, github.com/ghtdak/qtreactor ), которые позволяют инструментам GUI, таким как Qt, работать бок о бок с Twisted реактором.   -  person David K. Hess    schedule 05.12.2011
comment
@ypercube Я не был уверен, что twisted может сделать в этом отношении, поэтому задал более конкретный вопрос о том, как достичь вышеуказанного. Однако задним числом предложенный вами вопрос был бы лучше.   -  person Teifion    schedule 05.12.2011


Ответы (1)


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

from twisted.internet.protocol import ClientFactory
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor

class TTTClientProtocol(LineReceiver):
    def lineReceived(self, line):
        line = line.strip()
        if line == 'You are connected':
            self.sendLine(self.factory.username)
        else:
            print 'SERVER SAYS:', line

class TTTClientFactory(ClientFactory):
    protocol = TTTClientProtocol 

    def __init__(self, name):
        self.username = name


name = raw_input('Please enter your name: ')
print 'Connecting...'

reactor.connectTCP('localhost', 8007, TTTClientFactory(name))

reactor.run()

Я сделал его настолько простым, насколько мог, чтобы вы могли легко понять, но для реализации части чата мне понадобится код для чтения из stdin без блокировки реактора. Поскольку вы упомянули, что используете графический интерфейс вместо стандартного ввода / вывода терминала, на самом деле это намного проще - просто выберите реактор, совместимый с вашей библиотекой графического интерфейса, а затем используйте обычные события графического интерфейса.

Надеюсь, это поможет...

person nosklo    schedule 05.12.2011
comment
Если вам нужно было читать из stdin, для этого тоже есть API: twistedmatrix.com/documents/current/api/ - person Glyph; 06.01.2012