Removing clients from the reactor in Twisted - python

I have a simple TCP client which is connected to twisted using:
reactor.connectTCP(host, port, SomeClientFactory())
The program is able to receive a HUP signal to trigger a reload. I'd like to basically:
Remove the old clients
Reload config
Create new clients based upon new config
However, I can't seem to find a way to acheive the first of these points. Any tips?
Thanks

IReactorTCP.connectTCP returns an IConnector provider. As you can see on the definition of the IConnector interface, the disconnect method will do something like what you want. You can also use the protocol instance's transport attribute's loseConnection method, of course. The latter would be more suitable if there's any kind of cleanup you want the protocol to do before actually disconnecting, since you could put that work and a call to loseConnection at the end of a method like shutdown or quit or cleanup on the protocol class and then just call that.

Related

What is the best way of handling received messages in Twisted for Python?

I am a noob at Python and seeking some assistance with architecture. Here is my setup: I have a legacy client application written in LiveCode that runs in multiple locations to display synchronized information based on what the server demands. Think of this as a kiosk. This client piece is not going anywhere.
The server application is what I’m rewriting in Python. My goal is to have the server application running constantly, listening for client socket connections, and sending/receiving data to/from these clients. I have successfully passed messages between this LiveCode client application and a python script that uses Twisted for the socket handling, so now I need to start processing those messages. The code looks something like this:
from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor
class MessageListener(LineReceiver):
def __init__(self, users):
self.users = users
self.name = None
def connectionMade(self):
d = self.transport.getHost()
print("Connection established with {}:{}".format(d.host, d.port))
def connectionLost(self, reason):
print("Connection lost: {}".format(reason))
if self.name in self.users:
del self.users[self.name]
def dataReceived(self, line):
d = self.transport.getHost()
print("Received message from {}:{}...{}".format(d.host, d.port, line))
self.handle_GOTDATA(line)
def handle_GOTDATA(self, msg):
#convert "msg" to string and parse it into the necessary chunks
#*****Go do something based on the requestor and the command*****
#Use if-elif or dictionary to determine which function to run
#based on what the string tells us.
#Should these functions be defined here or in a separate class?
class MessageListenerFactory(Factory):
def __init__(self):
self.users = {} # maps user names to Chat instances
def buildProtocol(self, addr):
return MessageListener(self.users)
reactor.listenTCP(50010, MessageListenerFactory())
reactor.run()
A couple of questions:
The handle_GOTDATA() function is where I will take the received message, parse it out into the chunks that tell me what to do with the data, then call a different function depending on what needs to be done with that data.
Do I just define all 20 of these functions in this same “MessageListener” class, or do I write a separate class to keep all of these functions? I might get 10 messages at about the same time, and they may need to call the same function, so I wasn’t sure the best architecture approach here.
I also want to build a GUI to interact with the server for some troubleshooting and monitoring on occasion. I’m familiar with Tkinter and it would be fine for this, and I can write the GUI in a separate file and have it connect to the server over a socket as well. But would I use the same socket listener implemented above and just pass it similar messages? Or should I build a separate class and factory to listen for the GUI connections?
If you're going to use LineReceiver, you should not override dataReceived. Instead, override lineReceived. If your protocol isn't line-oriented, you probably don't want to use LineReceiver. Also you may want to consider using the Tubes interface in either case.
Do I just define all 20 of these functions in this same “MessageListener” class, or do I write a separate class to keep all of these functions?
You should probably put them on a different class. If you put them on MessageListener then you will have more difficulty testing, refactoring, and maintaining the code because your protocol logic is tightly coupled to your application logic.
Define an explicit interface that MessageListener uses to dispatch high-level events representing network actions. Then implement that interface appropriately for your particular application. Later, you can implement it differently for another application. Or you can write test doubles. Or you can change your protocol without changing your application logic. Decoupling the two pieces gives you lots of extra flexibility compared to smashing them both into one class.
I might get 10 messages at about the same time, and they may need to call the same function, so I wasn’t sure the best architecture approach here.
I think this is orthogonal but if it's an important enough part of your protocol or application logic, you might want to consider building some kind of vectorization into the explicit interface I mentioned above. Instead of appObj.doOneThing(oneThing) perhaps you have appObj.doSeveralThings([oneThing, anotherThing]).
I also want to build a GUI to interact with the server for some troubleshooting and monitoring on occasion. I’m familiar with Tkinter and it would be fine for this, and I can write the GUI in a separate file and have it connect to the server over a socket as well. But would I use the same socket listener implemented above and just pass it similar messages? Or should I build a separate class and factory to listen for the GUI connections?
That depends on the interactions you want to perform, I suppose. If this is a GUI with extra privileges compared to the normal client, you need a protocol and server with authentication and authorization functionality or you must not use the same server and protocol because you risk giving clients those extra privileges.
If you just want to simulate a real client with a kind of debug-friendly interface that lets you easily interact with the server in ways that a client would normally interact with it, but with an interface that makes this easier for you, you can (and presumably should) connect to the same server.

select() function for simultaneously I/O

I am trying to implement a multi-threading server which can handle with simultaneously read/write from client.
The server method:
The client connects to the server, when each message starts with the name of the user they want to send the message to, followed by '|'. It looks something like that: "USER_NAME|DATA".
After receiving the data, the server knows by a dictionary of {socket:username} where to send the data. Everything works great, except the fact that the client can't handle with simultaneously reading and writing. I searched for a method to handle that and i found the select() function, but with a lack of examples- i couldn't integrate that function in my code.
therefore I have 2 questions:
Is the select() function should be on the server side? will it be more efficient?
Is someone can demonstrate with a simple example how the select() method should look in the client side?
Thanks in advance!!!
Though select() will work, you have to use threads if you want to do other things while the system is blocked on the select.
Have a look at glib's GIO library. There you can connect callbacks to the actions you want to monitor or act on, for example the 'connect's from clients.
Just open a socket, and use its file descriptor to hang a gio.add_watch on. Here's a mini-tutorial on using giochannels.

Rpyc interfacing between two clients and one server

So right now I have rpyc client A that scrapes data and when it finds specific data it sends it to my rpyc server which is then stored. Lets say that I also have rpyc client B, C and D connected to my rpyc server as well. How can I make it so that the server can send that data directly to client C?
Since rpyc is symmetric, clients can pass callbacks for the server to call. The callbacks then get executed in the client process. That's probably the simplest and cleanest way to do what you want.
So your server needs to expose a new register_callback(client_callback) method, which stores the callbacks in a list. Then, whenever new data is received, you simply invoke all stored callbacks.
You'd also need to handle the case where a client which had registed a callback has already disconnected. It should be as simple as adding the correct try/except around the callback call (though I don't remember what's the actual exception type you'd need to catch).

Twisted IRCClient - using raw data without breaking class methods?

I'm working on a program using the Twisted IRCClient module, and am having a bit of a problem. There are several methods in the class that can be overloaded, for say when the client signs on to a server, or when the client receives a MOTD from a server. However, there don't seem to be any methods to deal with messages from the server itself, or to respond to ping queries that have a random number that needs to be sent back to the server.
Ideally I could implement these methods myself with the raw data from the server, using the lineReceived method of the class. However, it seems that when the lineReceived method is called by an incoming line, it gobbles up the line and the other class callbacks never fire. Is there a way around this problem? Thanks.
First, see 'METHODNAME' as Client method versus irc_'METHODNAME' in twisted for an explanation of how IRCClient dispatches messages. Then, take a look at irc_PING (which is already implemented, and already does the right thing).
Other server messages are handled via other similar callback methods.

Web Proxy to Simulate Network Problems

I need a way to simulate connectivity problems in an automated test suite, on Linux, and preferably from Python. Some sort of proxy that I can put in front of the web server that can hang or drop connections after one trigger or another (after X bytes transferred, etc) would be perfect.
It doesn't seem too hard to build, but I'd rather grab something pre-existing, if anyone has any good recommendations.
when i needed one, i found that building it yourself is the best thing..
start by raising a threaded server in python http://docs.python.org/dev/library/socketserver.html (you don't have to use the class itself).
and it's very simple:
in the new connection thread, you create a new socket and connects it to the real server.
then, you put both of them in a list and sends it to select.select (import select).
then, when socket x receive data - sends it to y. when socket y receives data sends it to x. (don't forget to close the socket when you receive empty string).
now you can do whatever you want..
if you need anything, i'm here..

Categories