Twisted Websocket — трансляция не работает при вызове из другого файла

#python #multithreading #websocket #twisted

#python #многопоточность #websocket #twisted

Вопрос:

Я настраивал сервер Websocket, который подключается к другому серверу и отправляет данные через сокет на веб-страницу (через функцию подписки). Пока я продолжаю вызывать функцию трансляции из файла, в котором выполняется websocket, все в порядке. Но при вызове метода широковещательной передачи из другого файла python, где моя push-функция печатает в командной строке, ни один клиент не получает сообщение.

Я предполагаю, что вызов трансляции из другого файла создает другой экземпляр, и при этом self.clients он пуст. Итак, подводя итог, подключенные клиенты получают трансляцию из loginGESI() , но не из моего второго файла scrptCallbackHandlerExample(subType) .

Был бы рад любой помощи!

вот мой файл Websocket:

 class BroadcastServerProtocol(WebSocketServerProtocol):

    def onOpen(self):
        self.factory.register(self)

    def connectionLost(self, reason):
        WebSocketServerProtocol.connectionLost(self, reason)
        self.factory.unregister(self)

class BroadcastServerFactory(WebSocketServerFactory):
    clients = []

    def __init__(self, url):
        WebSocketServerFactory.__init__(self, url)

    def register(self, client):
        if client not in self.clients:
            print("registered client {}".format(client.peer))
            self.clients.append(client)

    def unregister(self, client):
        if client in self.clients:
            print("unregistered client {}".format(client.peer))
            self.clients.remove(client)

    @classmethod
    def broadcast(self, msg):
        print("broadcasting message '{}' ..".format(msg))
        print(self.clients)
        for c in self.clients:
            c.sendMessage(msg.encode('utf8'))
            print("message sent to {}".format(c.peer))

def login():
    codesys = Test_Client("FTS_test")
    result = codesys.login()
    # FTS = codesys.searchForPackage("F000012")
    FTS = ["15900"];
    scrptContextId = [None] * len(FTS)
    itemContextIds_array = [None] * len(FTS)
    for i in range(0,len(FTS)):
        result, scrptContextId[i] = codesys.createSubscription(c_ScrptCallbackHandlerExample, 100, int(FTS[i]))
        print("SubscriptionRoomId: " str(scrptContextId[i]))
        result, itemContextIds_array[i], diagInfo = codesys.attachToSubscription(1, [FTS[i] '.speed'], [100])
        print("Subscription done for: " str(itemContextIds_array[i]))
        print("Subscription for: Speed")

    BroadcastServerFactory.broadcast(str(FTS[0]))


if __name__ == '__main__':

    # Logger Websocket
    log.startLogging(sys.stdout)
    # factory initialisieren
    ServerFactory = BroadcastServerFactory
    factory = ServerFactory("ws://127.0.0.1:9000")
    factory.protocol = BroadcastServerProtocol
    listenWS(factory)
    # reactor initialisieren
    webdir = File(".")
    web = Site(webdir)
    reactor.listenTCP(8080, web)

    reactor.callLater(5, login)

    reactor.run()
  

и вот мой файл подписки:

 # Launch of the CallbackHandler named in the createSubscription function 
# CallbackHandler describes what happens to a variable which changes its value
def scrptCallbackHandlerExample(subType):
    BroadcastServerFactory.broadcast('test')

    # Saves the value of the variables(s) in an array
    dataValue = []
    for i in range(0,subType.size):
        dataValue.append(subType.dataItems[i].node.dataValue)

    # Print variabel informations on the screen
    print "*****Callback - Data Change in a Variable*****"
    print( 'Subscription ID: %d' % subType.subscrId )
    for idx in range(0,subType.size):
        print( '** Item %d **' % idx )
        print( 'Item Id: %d' % subType.dataItems[idx].dataItemId )
        print( 'Item Node ID: %s' % subType.dataItems[idx].node.nodeId )
        print( 'Item data value: %s' % subType.dataItems[idx].node.dataValue )
        print( 'Item data type: %s' % subType.dataItems[idx].node.dataType )
        print( '******************************' )
# Define the type of the function as an eSubscriptionType
CB_FUNC_TYPE = CFUNCTYPE( None,  eSubscriptionType)
c_ScrptCallbackHandlerExample = CB_FUNC_TYPE( scrptCallbackHandlerExample )
  

С уважением

Комментарии:

1. Это работает не так. Другой скрипт будет выполняться как другой процесс и не будет иметь доступа к другому процессу. Для этого вам нужен какой-то IPC. docs.python.org/2/library/ipc.html

2. Я тем временем тоже читал. Не мог бы я обмениваться данными через глобальные переменные? Я пробовал это, но это все равно не работает в конце концов…. Другой идеей было включить другой файл python в мой файл сокета, но затем я получаю EOFError 10054: существующее соединение было принудительно закрыто удаленным хостом. И, в конце концов, я должен признать, что я довольно новичок в программировании и python вообще, IPC, вероятно, слишком много для меня прямо сейчас, нет ли гораздо более простого решения?

3. Просто чтобы было более понятно: два отдельных процесса с общим кодом подобны двум автомобилям с одинаковой моделью фар. Если вы включите свет на одной машине, абсолютно ничего не произойдет на другой машине.

Ответ №1:

Я нашел, по моему мнению, довольно аккуратный обходной путь.

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