简体   繁体   English

Twisted Python - 将数据推送到 websocket

[英]Twisted Python - Push data to websocket

I've a web-socket server which connects with the clients.我有一个与客户端连接的网络套接字服务器。 Following is the code:-以下是代码:-

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()

Clients get connected to the above code(server), and sends the data to the server.客户端连接到上述代码(服务器),并将数据发送到服务器。

Now, I've another python script, basically a scraper which scrapes the web, processes it and finally need to send the data to the connected clients.现在,我已经另一个python脚本,基本上是一个擦伤网页,处理它,最后需要将数据发送到连接的客户机的刮刀

script.py脚本文件

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

How can I achieve it??我怎样才能实现它? Any example would be of great help!!任何例子都会有很大帮助!!

UPDATE更新

After using Autobahn

I've a server that fetches data from 3rd party API.我有一个从 3rd 方 API 获取数据的服务器。 I want to send this data to all the connected web-socket clients.我想将此数据发送到所有连接的 web-socket 客户端。 Here is my code:-这是我的代码:-

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()

My Server will never receive a message or probably will receive, but as of right now there's no such use-case, hence no need for OnMessage event for this example).我的服务器永远不会收到或可能会收到消息,但截至目前还没有这样的用例,因此本示例不需要OnMessage事件)。

How do I write my send_data function in order to send data to all my connected clients??我如何编写我的send_data函数以便将数据发送到我所有连接的客户端??

You need to avoid this pattern when writing software with Twisted:使用 Twisted 编写软件时需要避免这种模式:

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

Twisted is a cooperative multitasking system. Twisted 是一个协作式多任务系统。 "Cooperative" means that you have to give up control of execution periodically so that other tasks get a chance to run. “合作”意味着您必须定期放弃对执行的控制,以便其他任务有机会运行。

twisted.internet.task.LoopingCall can be used to replace many while ... loops (particularly while True loops): twisted.internet.task.LoopingCall可用于替换许多while ...循环(尤其是while True循环):

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

This will call one_iteration every iteration_interval seconds.这将每iteration_interval one_iteration秒调用one_iteration In between, it will give up control of execution so other tasks can run.在这两者之间,它将放弃对执行的控制,以便其他任务可以运行。

Making one_iteration send a message to a client is just a matter of giving one_iteration a reference to that client (or those clients, if there are many).one_iteration向客户端发送消息只是给one_iteration一个对该客户端(或那些客户端,如果有很多)的引用。

This is a variation on the FAQ How do I make Input on One Connection Result in Output on Another .这是常见问题解答的变体如何在一个连接上进行输入导致另一个连接上的输出

If you have a ChatFactory with a dict containing all your clients, just pass that factory to one_iteration :如果您有一个ChatFactory ,其中包含所有客户端的 dict,只需将该工厂传递给one_iteration

LoopingCall(one_iteration, that_factory)

or

LoopingCall(lambda: one_iteration(that_factory))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM