【问题标题】:Twisted Websocket - Broadcasting doesn't work when called from another fileTwisted Websocket - 从另一个文件调用时广播不起作用
【发布时间】:2016-10-20 17:56:39
【问题描述】:

我正在设置一个 Websocket 服务器,它登录到另一个服务器并通过套接字将数据推送到网页(通过订阅功能)。只要我继续从运行 websocket 的文件中调用广播函数,一切都很好。但是从我的推送功能正在打印到命令行的另一个 python 文件调用广播方法,没有客户端收到消息。

我假设,从另一个文件调用广播会创建另一个实例,并且 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 )

问候

【问题讨论】:

  • 这样不行。其他脚本将作为其他进程运行,并且无法访问其他进程。你需要一种 IPC 来做到这一点。 docs.python.org/2/library/ipc.html
  • 我同时也在读书。我不能通过全局变量进行通信吗?我试过了,但它仍然不起作用......另一个想法是将另一个python文件包含到我的套接字文件中,但随后我得到一个EOFError 10054:远程主机强制关闭现有连接。毕竟我不得不承认我对编程和 python 还很陌生,IPC 对我来说可能太多了,难道没有更简单的解决方案吗?
  • 只是为了更清楚一点:使用共享代码的两个独立进程就像两辆具有相同型号前照灯的汽车。如果你打开一辆车的灯,另一辆车绝对不会发生任何事情。

标签: python multithreading websocket twisted


【解决方案1】:

在我看来,我发现了一个非常巧妙的解决方法。

每当调用我的订阅函数时,我都会将本地客户端连接到我的 websocket 服务器并向他发送一条带有新值的消息,然后 websocket 服务器将其推送到其他客户端。由于我仍在研究它,我无法发布任何代码,但功能已给出。因此,如果有人对解决方案感兴趣,请告诉我,我可以发布我的解决方案。

【讨论】:

    猜你喜欢
    • 2015-03-03
    • 2019-04-28
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多