简体   繁体   English

在Twisted中从一台服务器向另一台服务器发送消息

[英]Sending message from one server to another in Twisted

I'm a complete Twisted AND Python noob, so my apologies if any of my terminology is wrong or anything I've done is silly. 我是一个完整的Twisted和Python noob,所以如果我的任何术语出错或者我所做的任何事情都是愚蠢的,我会道歉。 Nonetheless.... 但是....

I've implemented my servers in the following way: 我用以下方式实现了我的服务器:

def makeServer(application, port):
    factory = protocol.ServerFactory()
    factory.protocol = MyChat
    factory.clients = []
    tempServer = internet.TCPServer(port, factory)
    tempServer.setServiceParent(application)
    return tempServer

application = service.Application("chatserver")
server1 = makeServer(application, port=1025)
server2 = makeServer(application, port=1026)
server3 = makeServer(application, port=1027)

Note that MyChat is an event handling class that has a "receiveMessage" action: 请注意,MyChat是一个具有“receiveMessage”操作的事件处理类:

def lineReceived(self, line):
    print "received", repr(line)
    for c in self.factory.clients:
       c.transport.write(message + '\n')

I want server1 to be able to pass messages to server2. 我希望server1能够将消息传递给server2。 Rather, I want server1 to be treated as a client of server2. 相反,我希望server1被视为server2的客户端。 If server1 receives the message "hi" then I want it to send that same exact message to server2. 如果server1收到消息“hi”,那么我希望它将相同的确切消息发送到server2。 The only thing server1 needs to be able to do is to send the message it received from its client to server2. server1唯一需要做的就是将从客户端收到的消息发送到server2。

How can I accomplish this? 我怎么能做到这一点?

NOTE: You can totally change the way I'm implementing my server if it helps. 注意:如果有帮助,您可以完全改变我实现服务器的方式。

Different parts of your application can interact with each other using method calls. 应用程序的不同部分可以使用方法调用相互交互。

Send a message to server2 really just means Call a method on one of the objects related to server2 . 向server2发送消息实际上只是意味着在与server2相关的其中一个对象上调用方法

For example, in MyChat , you might have: 例如,在MyChat ,您可能有:

def lineReceived(self, line):
   print "received", repr(line)
   for c in self.factory.clients:
       c.transport.write(message + '\n')
   for server in self.factory.otherServers:
       server.otherServerMessage(self, line)

This supposes a couple things: 这假设了几件事:

  • You add a new otherServers attribute to your factory. 您将新的otherServers属性添加到工厂。 Its contents are objects related to the other listening servers you have set up. 其内容是与您设置的其他侦听服务器相关的对象。 These might be factory objects or protocol objects. 这些可能是工厂对象或协议对象。 It depends on what's most convenient based on what you intend to do with the message. 这取决于根据您打算如何处理消息最方便的内容。
  • You give those related objects a new method, otherServerMessage , to handle messages delivered this way. 您为这些相关对象提供了一个新方法otherServerMessage来处理以这种方式传递的消息。 If you were to deliver the messages directly to MyChat.lineReceived (which you easily could, if you wanted) then I would expect you to end up with infinite recursion; 如果您要将消息直接发送到MyChat.lineReceived (如果您MyChat.lineReceived ,您很容易就可以),那么我希望您最终得到无限递归; having a different method lets you differentiate between messages received from a client and messages received from another server. 使用不同的方法可以区分从客户端接收的消息和从其他服务器接收的消息。

You need just declare clients inside your server, like this: 您只需在服务器中声明客户端,如下所示:

factory = SomeClientFactory('ws://127.0.0.1')            
connectWS(factory)

and in your Client Class: 在您的客户类中:

class SomeClient(WebSocketClientProtocol):

    def __init__(self):
       pass

    def sendCommand(self):    

        self.sendMessage('A message to another server')

    def onOpen(self):
        self.sendCommand()

    def onClose(self, wasClean, code, reason):
        print(reason)

    def onMessage(self, payload, isBinary):
        print('A answer from another server')

class SomeClientFactory(WebSocketClientFactory):

    def __init__(self, url): 
        WebSocketClientFactory.__init__(self,url)

        self.proto = DeltaClient()        
        self.proto.factory = self

    def buildProtocol(self, addr):        
        return self.proto  

Tip: use a "Controller" class to manage that instances of clients inside your servers. 提示:使用“Controller”类来管理服务器内的客户端实例。

You will probably need to implement a separate client. 您可能需要实现一个单独的客户端。 It is possible that an object can be both a client and a server, but I doubt it will be worth it and you are likely to run into trouble. 一个对象可能既是客户端又是服务器,但我怀疑它是否值得,你可能会遇到麻烦。

I suggest that the server instantiates a client object, which you connect to the 'next' server. 我建议服务器实例化一个客户端对象,连接到“下一个”服务器。 The client can for example be an instance variable on the server. 例如,客户端可以是服务器上的实例变量。

Example: 例:

class MyChat(LineReceiver):
    def connectionMade(self):
        print "Proxy: connected"
        factory = protocol.ClientFactory()
        class Proxy(protocol.Protocol):
            def relayMessage(self, msg):
                self.transport.write(msg)
        factory.protocol = Proxy
        point = TCP4ClientEndpoint(reactor, "localhost", 1025)
        conn = point.connect(factory)
        conn.addCallback(self.hasConnection)
    def hasConnection(self, client):
        print "Proxy: Connected to relay", client
        self.client = client
    def lineReceived(self, line):
        print "Proxy: received", repr(line)
        self.client.transport.write(line+"\n")

class MyEcho(LineReceiver):
    def lineReceived(self, line):
        print "Echo:  received", repr(line)

factory = protocol.ServerFactory()
factory.protocol = MyChat
reactor.listenTCP(1024, factory)

factory = protocol.ServerFactory()
factory.protocol = MyEcho
reactor.listenTCP(1025, factory)

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

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