【问题标题】:Twisted Python - Push data to websocketTwisted Python - 将数据推送到 websocket
【发布时间】:2017-07-05 06:35:18
【问题描述】:

我有一个与客户端连接的网络套接字服务器。以下是代码:-

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

class Chat(LineReceiver):

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

    def connectionMade(self):
        self.sendLine("What's your name?")

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

    def lineReceived(self, line):
        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):
        # Need to send the message to the connected clients.


class ChatFactory(Factory):

    def __init__(self):
        self.users = {} # maps user names to Chat instances

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


reactor.listenTCP(8123, ChatFactory())
reactor.run()

客户端连接到上面的代码(服务器),并将数据发送到服务器。

现在,我有另一个 Python 脚本,基本上是一个 scraper,它scrapes 网络、处理它并最终需要将数据发送到连接的客户端。

script.py

while True:
    # call `send_message` function and send data to the connected clients.

我怎样才能实现它?任何例子都会有很大帮助!

更新

After using Autobahn

我有一个从 3rd 方 API 获取数据的服务器。我想将此数据发送到所有连接的 web-socket 客户端。这是我的代码:-

class MyServerProtocol(WebSocketServerProtocol):
    def __init__(self):
        self.connected_users = []
        self.send_data()

    def onConnect(self, request):
        print("Client connecting: {0}".format(request.peer))
        
    def onOpen(self):
        print("WebSocket connection open.")
        self.connected_users.append(self)  # adding users to the connected_list

    def send_data(self):
        # fetch data from the API and forward it to the connected_users.
        for u in self.users:
            print 1111
            u.sendMessage('Hello, Some Data from API!', False)

    def onClose(self, wasClean, code, reason):
        connected_users.remove(self)  # remove user from the connected list of users
        print("WebSocket connection closed: {0}".format(reason))


if __name__ == '__main__':

    import sys

    from twisted.python import log
    from twisted.internet import reactor

    factory = WebSocketServerFactory(u"ws://127.0.0.1:9000")
    factory.protocol = MyServerProtocol    

    reactor.listenTCP(9000, factory)
    reactor.run()

我的服务器永远不会收到消息,或者可能会收到消息,但目前还没有这样的用例,因此这个例子不需要OnMessage 事件。

如何编写我的send_data 函数以向所有连接的客户端发送数据??

【问题讨论】:

  • send_message 是什么? “websockets”在哪里?
  • send_message 将是一个函数,通过该函数将数据推送到连接的 Web 客户端(套接字)?
  • "websockets" 是一个特定的协议 - en.wikipedia.org/wiki/WebSocket - 您的示例代码中似乎没有使用它。如果你真的需要 WebSockets,看看 Autobahn。

标签: python sockets websocket twisted autobahn


【解决方案1】:

使用 Twisted 编写软件时需要避免这种模式:

while True:
    # call `send_message` function and send data to the connected clients.

Twisted 是一个协作式多任务系统。 “合作”意味着您必须定期放弃对执行的控制,以便其他任务有机会运行。

twisted.internet.task.LoopingCall 可用于替换许多while ... 循环(尤其是while True 循环):

from twisted.internet.task import LoopingCall
LoopingCall(one_iteration).start(iteration_interval)

这将每隔iteration_interval 秒调用一次one_iteration。在这两者之间,它会放弃对执行的控制,以便其他任务可以运行。

one_iteration 向客户端发送消息只是为one_iteration 提供对该客户端(或那些客户端,如果有很多的话)的引用。

这是常见问题解答How do I make Input on One Connection Result in Output on Another 的一个变体。

如果你有一个 ChatFactory 包含所有客户的字典,只需将该工厂传递给 one_iteration

LoopingCall(one_iteration, that_factory)

LoopingCall(lambda: one_iteration(that_factory))

【讨论】:

  • 我想你没有理解我的问题。让我重新定义一下。请查看更新后的问题。
猜你喜欢
  • 1970-01-01
  • 2016-03-25
  • 1970-01-01
  • 1970-01-01
  • 2014-06-08
  • 2011-12-27
  • 1970-01-01
  • 1970-01-01
  • 2020-01-14
相关资源
最近更新 更多