How to interrupt in python - python

my subscribe function will call on_message function everytime that have message from websocket
and unsubscribe when message is STOP
is_sub = True
def on_message(msg):
print(msg)
if msg == "STOP":
unsubscribe(key)
is_sub = False
#continue to code
print("Start")
key = subscribe(on_message)
while is_sub:
print("on sub")
time.sleep(1)
#cotinue here
print("End")
without while loop the code will end and not recive any more message.
I want to find the better way (without time.sleep) to interrupt and continue the code
ps. I can't edit subscribe and unsubscribe function

You could run the instance of your websocket server in a separate thread. This will allow you to still continue to run your main thread while your webserver is listening to incoming messages.

I think you can't do it without a while loop. If you want to free your main thread you can do your message subscription on separate thread but that's not what you want I guess. Most WebSocket client would provide a method to keep the connection alive. for example this provides a run_forever() methods which does the 'while loop' part for you. If you are using a client there is a chance that they provide methods for keeping the connection alive. I suggest you go through the documentation once more.

If you want to continue the code, you could use the continue() command and if you want to stop, you could use the break() command.

Related

How do i make a socket in python to be able to receive but also to send in a while true loop?

So, if i want to make a "chat" with python sockets, i need to be able to write a message and send it anytime i want, maybe by doing something like this:
while True:
msg = input()
socket.send(msg)
But, if i do that, i will not be able to use socket.recv() without making python wait for a message and stop the program until it gets received, i tried to solve this with threading but it of course can't work like that. How can i solve this?
Below the attempt by threading.
def receive():
while True:
client.recv(2048)
looprecv = threading.Thread(target=receive())
looprecv.start()
while True:
message = input("messaggio: ")
send(message)
if message == "!exit":
break

How can i interrupt my function to stop sending data to my angular server

I have my Angular server which plots my Data I get from a python-bokeh Server. On my Frontend, I have a Button which calls my function getData(). This function sends a Message over a Websocket connection to my Python Server. In this message, there is a String which function should be called. When the python server received the message "getData" he collects the Data and sends them to the angular server. But now I want to stop sending data to my angular server(because the Stop Button is pressed).
My Problem: Either I do a while loop to send data the whole time, but then I cant stop the function or I don't use a while loop but then I have to send messages to my python server the whole time with a time delay.
In Python my Code ist something like :
while websocketconnection == true:
imp = getMessage()
FunctionString == imp['name']
if(FunctionString == 'getData'):
*get the Data and send them back to angular*
if(FunctionString == 'Stop'):
*close socket connection(not websocket connection)*
...(*some more not relevant functions*)
I will recommend a way I used in the past. You can use multithreading to handle such bahaviour.
Then you either do quick and dirty:
in another thread you assign global value of websocketconnection to be False
or
you can create some Event and Signal, so once you trigger button it will perform some logic
PS
in python you can do just:
while websocketconnection:
imp = getMessage()
..............

Getting user input while letting other code run

I'm making a Discord client (in old discord.py). Discord requires regular communications or else it will close the connection and subsequently make my program crash. My client requires user input (via input command) for the message which prevents the request from being made and making it crash.
Is there a way to ask for user input and let other code run in the background?
Use threading:
from _thread import start_new_thread as thread
def othercode(): # Code which will execute during input
print("bloop")
def inputcode(): # Code which will recieve input
global thing
thing = input("input: ")
thread(othercode) # Start a thread
inputcode() # STart the input script on the main thread

Responding in MQTT with Python

I'm having a little bit of a delay-issue in my MQTT Python (v2.7) script that has me wondering...
So I have one device request a function to another device. Let's call them A and B.
So A sends out a MQTT message to do something, and B does that function. I have A send it out by a normal publish method. There are no issues here.
B gets the published message with the part:
def on_message(client, userdata, msg):
if msg.topic == "action":
>> then do something here <<
Also there seem to be no issues here. It gets the message and it performs the action.
The problem gets here when I try to report back what it's going, which looks like this:
def on_message(client, userdata, msg):
if msg.topic == "action":
>> then do something here <<
client.publish("report", payload=message1, qos=2, retain=False)
>> then do some more action here <<
client.publish("report", payload=message2, qos=2, retain=False)
The problem is not that it doesn't do the action nor that it doesnt do the action, but it seems that it will do both, but rather in a very strange order, like:
action
action
(several seconds wait)
message1
message2
This doesn't seem right? How can I make the script send out the message before it's doing the second part?
This is working as expected.
The network loop is a single thread which is already handling the incoming message. The publishes are queued up until the on_message function completes and then the network loop will handle these queued publishes
TCP stack is asynchronous. When you call for sending data, it does not mean that it goes out immediately. There is an event loop running behind your code. If you want to do something in sequence, you must break your sequential tasks into separate functions and call them on next on_publish() when the message was really sent out.
I was able to send out messages using the library:
import paho.mqtt.publish as mqttc
and using a:
mqttc.single("report", payload=message1, qos=2, hostname=XXXX, port=XXXX)
which will follow the natural flow of the script and still send out the message.

Twisted Python pause/postpone reactor

I'm pretty new to twisted, I have an HTTP client that queries a server that has rate limit, when I hit this limit the server responds with HTTP 204, so when I'm handling the response I'm doing probably something nasty, like this:
def handleResponse(r, ip):
if r.code == 204:
print 'Got 204, sleeping'
time.sleep(120)
return None
else:
jsonmap[ip] = ''
whenFinished = twisted.internet.defer.Deferred()
r.deliverBody(PrinterClient(whenFinished, ip))
return whenFinished
I'm doing this because I want to pause all the tasks.
Following there are 2 behaviours that I've in my mind, either re-run the tasks that hit 204 afterwards in the same execution (don't know if it's possible) or just log the errors and re-run them afterwards in another execution of the program. Another problem that may raise is that I've set a timeout on the connection in order to cancel the deferred after a pre-defined amount of time (see the code below) if there's no response from the server
timeoutCall = reactor.callLater(60, d.cancel)
def completed(passthrough):
if timeoutCall.active():
timeoutCall.cancel()
return passthrough
d.addCallback(handleResponse, ip)
d.addErrback(handleError, ip)
d.addBoth(completed)
Another problem that I may encounter is that if I'm sleeping I may hit this timeout and all my requests will be cancelled.
I hope that I've been enough precise.
Thank you in advance.
Jeppo
Don't use time.sleep(20) in any Twisted-based code. This violates basic assumptions that any other Twisted-based code that you might be using makes.
Instead, if want to delay something by N seconds, use reactor.callLater(N, someFunction).
Once you remove the sleep calls from your program, the problem of unrelated timeouts being hit just because you've stopped the reactor from processing events will go away.
For anyone stumbling across this thread, it's imperative that you never call time.sleep(...); however, it is possible to create a Deferred that does nothing but sleep... which you can use to compose delays into a deferred chain:
def make_delay_deferred(seconds, result=None):
d = Deferred()
reactor.callLater(seconds, d.callback, result)
return d

Categories