是否可以在两个正在运行的进程之间共享套接字对象?
为了简化问题,假设我们有两个文件s1.py
和s2.py
。两者都是在不同端口上侦听的tcp服务器。
s1.py body
from twisted.internet import reactor, protocol
CLIENTS = []
class Echo(protocol.Protocol):
def connectionMade(self):
CLIENTS.append(self)
def dataReceived(self, data):
self.transport.write(data)
def connectionLost(self):
CLIENTS.remove(self)
def main():
factory = protocol.ServerFactory()
factory.protocol = Echo
reactor.listenTCP(8000, factory)
reactor.run()
main()
和s2.py
from twisted.internet import reactor, protocol
class Echo(protocol.Protocol):
def dataReceived(self, data):
for socket in list_of_serialized_redis_CLIENTS_socket_object:
socket.transport.write(data)
def main():
factory = protocol.ServerFactory()
factory.protocol = Echo
reactor.listenTCP(8001, factory)
reactor.run()
main()
是否可以与s1.py共享s1.py中的CLIENTS
?
也许有一些方法可以序列化CLIENTS
并将其存储在redis中。
答案 0 :(得分:0)
使用socket.share()
可能不像您想象的那么直截了当。
首先,它是Windows独有的功能,Windows是Twisted最少关注的平台。
在Twisted中访问低级socket
对象可能很棘手,因为幕后发生了很多事情,如果更改可能会导致奇怪的结果。
换句话说,它确实可以走这条路,但不建议这样做。
如果您对新解决方案持开放态度,我认为RPC式服务器将解决您的问题。
我的想法是,由于连接对象位于s1
中,因此只需创建一个远程进程即可实现"做东西"对那些联系。
其他进程可以连接到该服务器并在s1
本地对象上执行函数。 Twisted' Perspective Broker是您可以利用的现成解决方案。
s1.py
from twisted.internet import reactor, protocol, endpoints
from twisted.spread import pb
class Echo(protocol.Protocol):
def connectionMade(self):
self.factory.client_set.add(self)
def connectionLost(self, reason):
self.factory.client_set.remove(self)
class Remote(pb.Root):
def __init__(self, client_set):
self.client_set = client_set
def remote_s1_write(self, data):
msg_tmpl = 'From s1...{0}'
for client in self.client_set:
response = msg_tmpl.format(data).encode('utf-8')
client.transport.write(response)
def main():
client_set = set() # container will be shared between the 2 servers
# setup Echo server
factory = protocol.ServerFactory()
factory.protocol = Echo
factory.client_set = client_set
echo_server = endpoints.TCP4ServerEndpoint(reactor, interface='localhost', port=8000)
echo_server.listen(factory)
# setup PB server
pb_root = Remote(client_set)
pb_factory = pb.PBServerFactory(pb_root)
pb_server = endpoints.TCP4ServerEndpoint(reactor, interface='localhost', port=7999)
pb_server.listen(pb_factory)
reactor.run()
main()
s2.py
from twisted.internet import reactor, protocol, endpoints
from twisted.spread import pb
class Echo(protocol.Protocol):
def dataReceived(self, data):
remote = self.factory.pb_factory.getRootObject()
remote.addCallback(lambda obj: obj.callRemote('s1_write', data))
remote.addCallback(lambda echo: 's1 said: {0}'.format(data))
remote.addErrback(lambda reason: 'error: {0}'.format(str(reason.value)))
remote.addCallback(lambda response: print(response))
self.transport.write(data)
def main():
# connect to s1's PB server
pb_factory = pb.PBClientFactory()
pb_connection = endpoints.TCP4ClientEndpoint(reactor, host='localhost', port=7999)
pb_connection.connect(pb_factory)
# setup Echo server
factory = protocol.ServerFactory()
factory.protocol = Echo
factory.pb_factory = pb_factory
echo_server = endpoints.TCP4ServerEndpoint(reactor, interface='localhost', port=8001)
echo_server.listen(factory)
reactor.run()
main()
我采取了自由并更新了语法。试试这段代码,看看它是否有效,并询问您是否有任何问题。