2015-03-01 14 views
5

Tôi muốn gọi phương thức sendMessage từ bên ngoài của MyServerProtocol lớp và gửi tin nhắn đến các khách hàng được kết nối. Tôi sử dụng threading để thực hiện việc này.sendMessage từ bên ngoài trong autobahn chạy trong thread riêng biệt

Khi tôi sử dụng mã này:

from autobahn.twisted.websocket import WebSocketServerProtocol, WebSocketServerFactory 
from twisted.internet import reactor 
import threading 

class MyServerProtocol(WebSocketServerProtocol): 
    def onConnect(self, request): 
     print("Client connecting: {0}".format(request.peer)) 

    def onOpen(self): 
     print("WebSocket connection open.") 

    def onMessage(self, payload, isBinary): 
     if isBinary: 
      print("Binary message received: {0} bytes".format(len(payload))) 
     else: 
      print("Text message received: {0}".format(payload.decode('utf8'))) 

     self.sendMessage(payload, isBinary) 

    def onClose(self, wasClean, code, reason): 
     print("WebSocket connection closed: {0}".format(reason)) 


class Connection(threading.Thread): 
    def __init__(self): 
     super(Connection, self).__init__() 

    def run(self): 
     self.factory = WebSocketServerFactory("ws://localhost:9000", debug=False) 
     self.factory.protocol = MyServerProtocol 
     reactor.listenTCP(9000, self.factory) 
     reactor.run(installSignalHandlers=0) 

    def send(self, data): 
     reactor.callFromThread(self.factory.protocol.sendMessage, self.factory.protocol, data) 

connection = Connection() 
connection.daemon = True 
connection.start() 
connection.send('test') 

lỗi này xảy ra:

connection.send('test') 
reactor.callFromThread(self.factory.protocol.sendMessage, self.factory.protocol, data) 
AttributeError: 'Connection' object has no attribute 'factory' 

Nếu tôi cố gắng xóa bỏ dòng connection.send('test'), lỗi này xảy ra:

TypeError: 'NoneType' object is not iterable 

gì vấn đề với mã của tôi là gì?

Tôi có làm đúng cách này không? Hoặc là có một cách khác để gửi tin nhắn cho khách hàng từ bên ngoài của lớp giao thức?

Cảm ơn.

+0

Có self.factory tồn tại khi bạn gọi gửi không? Cố gắng đặt một giấc ngủ giữa start() và send() và kiểm tra. Ngoài ra, hãy sử dụng trình gỡ lỗi. – Raito

+0

Bạn đã bao giờ tìm ra cách để làm điều này? Tôi đang gặp vấn đề tương tự. – someuser

Trả lời

0

add self.factory để bạn "init (tự):" xem dưới đây:

from autobahn.twisted.websocket import WebSocketServerProtocol, WebSocketServerFactory 
    from twisted.internet import reactor 
    import threading 

    class MyServerProtocol(WebSocketServerProtocol): 
     def onConnect(self, request): 
      print("Client connecting: {0}".format(request.peer)) 

     def onOpen(self): 
      print("WebSocket connection open.") 

     def onMessage(self, payload, isBinary): 
      if isBinary: 
       print("Binary message received: {0} bytes".format(len(payload))) 
      else: 
       print("Text message received: {0}".format(payload.decode('utf8'))) 

      self.sendMessage(payload, isBinary) 

     def onClose(self, wasClean, code, reason): 
      print("WebSocket connection closed: {0}".format(reason)) 


    class Connection(threading.Thread): 
     def __init__(self,factory): 
      super(Connection, self).__init__() 
      self.factory=WebSocketServerFactory("ws://localhost:9000", debug=False) 
     def run(self): 
      self.factory.protocol = MyServerProtocol() 
      reactor.listenTCP(9000, self.factory) 
      reactor.run(installSignalHandlers=0) 

     def send(self, data): 
      reactor.callFromThread(self.factory.protocol.sendMessage, self.factory.protocol, data) 

    connection = Connection() 
    connection.daemon = True 
    connection.start() 
    connection.send('test') 
+0

Liệu luồng này có xử lý nhiều kết nối của các đồng nghiệp không? – hietpasd

3

là [có] một cách khác để gửi cho khách hàng thông điệp từ bên ngoài của lớp máy chủ?

Tôi làm như thế này để gửi tin nhắn. Tôi sử dụng twisted để chạy ứng dụng web của mình.

import json 
from autobahn.twisted.websocket import WebSocketServerProtocol 
from twisted.internet import reactor 

class MyProtocol(WebSocketServerProtocol): 
    connections = list() 

    def onConnect(self, request): 
     self.connections.append(self) 

    def onClose(self, wasClean, code, reason): 
     self.connections.remove(self) 

    @classmethod 
    def broadcast_message(cls, data): 
     payload = json.dumps(data, ensure_ascii = False).encode('utf8') 
     for c in set(cls.connections): 
      reactor.callFromThread(cls.sendMessage, c, payload) 


# Somewhere else 
MyProtocol.broadcast_message({'greeting': 'Hello world'}) 

Tôi không biết nếu nó là The Right Way ™, nhưng nó hoạt động tốt đối với tôi.

Các vấn đề liên quan