[英]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.