2017-07-05 87 views
-1

我有一個與客戶端連接的web-socket服務器。以下是代碼: -Twisted Python - 將數據推送到websocket

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腳本,基本上是一個報廢web,處理它並最終需要將數據發送到連接的客戶端的報廢者。

script.py

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

我怎樣才能實現呢?任何例子都會有很大的幫助!

UPDATE

After using Autobahn

我已經從第三方API獲取數據的服務器。我想將這些數據發送到所有連接的網絡套接字客戶端。這裏是我的代碼: -

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函數以便將數據發送給所有連接的客戶端?

+1

什麼'send_message'? 「websockets」在哪裏? –

+0

'send_message'將通過哪些功能將數據推送到連接的Web客戶端(套接字)? – PythonEnthusiast

+1

「websockets」是一個特定的協議 - https://en.wikipedia.org/wiki/WebSocket - 它似乎沒有用於你的示例代碼。如果您確實需要WebSockets,請參考Autobahn。 –

回答

0

你需要扭轉編寫軟件時,爲了避免這種模式:

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) 

這將調用one_iterationiteration_interval秒。在這之間,它將放棄對執行的控制,以便其他任務可以運行。

製作one_iteration發送消息給客戶只是給one_iteration一個引用該客戶端(或那些客戶端,如果有很多)。

這是FAQ 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)) 
+0

我想你沒有理解我的問題。讓我重新來一下。請看更新的問題。 – PythonEnthusiast