RabbitMQ machine to machine - raspberry-pi

I'm trying to connect rabbitMQ in one machine (Windows 10) to other machine (Raspberry pi 4). The windows machine is the producer, and the pi is the receiver. Both are connected to the same network, and defined with the same localhost. Although the message is sent correctly to the queue, it is not received by the Pi.
Is there any steps that I'm missing?
Below is the producer code (python in PC- Windows)
import pika
connection = pika.BlockingConnection(
pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
channel.queue_declare(queue='my-queue')
channel.basic_publish(exchange='', routing_key='my-queue', body='Hello World from windows!!')
print(" [x] Sent 'Hello World from windows!'")
connection.close()
Consumer code (in Pi)
import pika
host = 'localhost'
queue = 'my-queue'
def on_message(ch, method, properties, body):
message = body.decode('UTF-8')
print(message)
def main():
connection_params = pika.ConnectionParameters(host=host)
connection = pika.BlockingConnection(connection_params)
channel = connection.channel()
channel.queue_declare(queue=queue)
channel.basic_consume(queue=queue, on_message_callback=on_message,
auto_ack=True)
print('Subscribed to ' + queue + ', waiting for messages...')
channel.start_consuming()
if __name__ == '__main__':
main()

Related

MicroPython: How to auto reconnect STA to AP if AP gets power cycled?

I am writing a python code on ESP8266 using MicroPython to configure it as STA, connect it to an AccessPoint and then send some data on UDP Socket.
I want to implement a scenario where in case if AccessPoint due to some reason goes down and comes back after some time, the the ESP8266 acting as STA should automatically reconnect to specific AP.
I am not sure if there's a functionality to setup a callback on STA if it misses few Beacons (e.g. upto 5 or 10)
This is the code that I have written so far:
import network
import esp
import gc
import time
try:
import usocket as socket
except ModuleNotFoundError as e:
import socket
def main():
count = 0
esp.osdebug(None)
gc.collect()
sta = network.WLAN(network.STA_IF)
sta.active(True)
sta.connect('HumidityServer', 'password#123')
while not sta.active():
pass
print('Connection successful')
print(sta.ifconfig())
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('192.168.45.1', 9000))
while True:
str_to_send = "Hello ESP8266: " + str(count)
s.sendto(str_to_send, ('192.168.45.1', 9000))
request = s.recv(1024)
print('Content = %s' % str(request))
count = count + 1
time.sleep(5)
if __name__ == "__main__":
main()

Why does Rasp Pi Pico can not connect to TCP Server after some point?

I use Raspberry Pi Pico with ESP8266 WiFi module, and I am trying to write a TCP client. Rasp Pi Pico is able to send AT commands and receive responses and send data through UART. Also the TCP client is able to send data to the TCP server, which runs in my laptop. However the problem is that the client is not able to connect to the server after some point.
Let me first show the server-side code. In server, I am trying to receive data basically. ConnectionResetError was a problem for me so I wrote the following except block. I am not sure it is buggy or not, since I'm kind of a noob in this area.
import socket
HOST = ""
PORT = 8080
mysocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
mysocket.bind((HOST, PORT))
mysocket.listen(1)
while True:
print("Waiting...")
conn, addr = mysocket.accept()
print('[SERVER] - Connected from: %s' % str(addr))
while True:
try:
request = conn.recv(1024)
if not request:
break
conn.sendall(request.upper())
print('[SERVER] - Received Data: %s' % str(request))
except ConnectionResetError as cr_err:
break
conn.close()
print("[SERVER] - Disconnected")
Here is my client-side code. In client, I wrote two helper classes called ESP8266 and Sensor, in which I control the WiFi module and read analog value from a sensor. Pico first tries to start WiFi module, afterwards it tries to connect to TCP server and send data. After some point it does not connect to the TCP server, so it restart the WiFi module and reconnects.
class EndDevice:
def __init__(self, sensor_id):
self.__wifi_module = ESP8266(UART_PIN, BAUDRATE)
self.__sensor = Sensor(sensor_id, SENSOR_PIN)
def start(self):
self.__wifi_module.start()
self.__wifi_module.set_mode(STATION_MODE)
self.__wifi_module.join_access_point(AP_NAME, AP_PWD)
def reconnect(self):
self.__wifi_module.restart()
self.__wifi_module.set_mode(STATION_MODE)
self.__wifi_module.join_access_point(AP_NAME, AP_PWD)
def run(self):
retry_count = 0
while True:
if self.__wifi_module.start_connection("TCP", SERVER_HOST, SERVER_PORT):
self.__wifi_module.send_data(
str(self.__sensor.generate_package()))
self.__wifi_module.close_connection()
else:
retry_count += 1
if retry_count == MAX_RETRY:
break
if __name__ == "__main__":
pico = EndDevice("SM-0")
pico.start()
while True:
pico.run()
pico.reconnect()
Finally I will share some of the methods in classes ESP8266 and UARTHandler (which is used in ESP8266), so you can see if I do anything non-sense.
start_connection method in ESP8266 is as follows. In this method, I tried to send the corresponding AT command to connect to a TCP server. In the method self.__uart_handler.send_receive_cmd timeout duration is 2000ms, and other parameters are AT command, connection_type (TCP), server IP address and server port, in order.
def start_connection(self, conn_type, remote_ip, remote_port):
conn_type, remote_ip = "\"{}\"".format(conn_type), "\"{}\"".format(remote_ip)
response = self.__uart_handler.send_receive_cmd(2000, CONN_START, conn_type, remote_ip, str(remote_port))
if "OK" in response:
self.__log("Connected to {} at port {}.".format(remote_ip, remote_port))
return True
else:
self.__log("Failed to create a connection with {} at port {}.".format(remote_ip, remote_port))
return False
send_receive_cmd method in UARTHandler is as follows. In this method I use lots of helper methods as you can see, however they are just formatting and writing to UART or reading from UART. I also insert a timeout between UART-read and UART-write
def __generate_cmd(self, cmd, *args):
if len(args) != 0:
cmd += "="
for idx, each in enumerate(args):
cmd += str(each)
if idx != len(args)-1:
cmd += ","
cmd += "\r\n"
return cmd
def __send_cmd(self, cmd, *args):
sent_cmd = self.__generate_cmd(cmd, *args)
self.__uart.write(sent_cmd)
def __receive_response(self, cmd):
response = self.__uart.read()
try: return response.decode('utf-8')
except: return response
def send_receive_cmd(self, timeout, cmd, *args):
self.__send_cmd(cmd, *args)
utime.sleep_ms(timeout)
return self.__receive_response(self.__generate_cmd(cmd, *args))
Let me ask my question again. This codes are working properly in starting-restarting and sending data for (let me say) 3 connections. However, after some connect-disconnect later, TCP client is not able to make a connection with TCP server. Again after some failed connection attempt, WiFi module is restarted and TCP connection is made and working properly again.

Connecting two computers in different networks using socket and Port forwarding

I have set up a simple client-server communication code and it works well in my computer when my computer itself acts as a server and the client.
Now I am trying to run this same code on two different computers in different networks( different locations) where my computer will act as a server and my friend's computer as a client.
I have done port forwarding in my router as well as in my friend's router for the port which we are trying to communicate. We both have set up a static IP in our internal network behind the router. We both had shutdown the firewall while running the code.
I am running my code on Jupiter notebook and the same is my friend too.
here is my server code:
import socket
import threading
HEADER = 64
PORT = 5064
SERVER = '0.0.0.0'
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "quit"
Receive_from_client = "get info"
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(ADDR)
def handle_client(conn, addr):
print("\n" + f"[NEW Connection] detected from IP: {addr[0]} & Port:{addr[1]} ")
conn.send(f"connected to server {ADDR}".encode(FORMAT))
connected =True
while connected:
msg_length = conn.recv(HEADER).decode(FORMAT) # decode the msg from byte to utf-8 format
if msg_length:
msg_length = int(msg_length)
msg = conn.recv(msg_length).decode(FORMAT)
if msg == DISCONNECT_MESSAGE:
connected = False
print(f" [Client][{addr}] {msg}")
print("Your session is disconnected")
break
if msg == Receive_from_client:
print("\n" + f"Send your msg to client with IP: {addr[0]}")
thread = threading.Thread(target = send2client, args = (conn, addr))
thread.start()
print(f" [Client][{addr}] {msg}")
conn.send(f"Msg received by server with IP:{addr[0]}".encode(FORMAT))
conn.close()
server.close()
def start():
server.listen()
print("\n"+ f"[LISTENING] Server is listening from IP: {SERVER} ")
while True:
conn, addr = server.accept()
thread = threading.Thread(target = handle_client, args = (conn, addr))
thread.start()
Here is the client code
import socket
import threading
HEADER = 64
PORT = 5064
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "quit"
SERVER = '103.192.207.250' # SERVERS public IP
ADDR = (SERVER, PORT)
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(ADDR)
def send2server():
while True:
msg = input()
message = msg.encode(FORMAT)
msg_lenght = len(message)
send_length = str(msg_lenght).encode(FORMAT)
send_length += b' '*(HEADER - len(send_length))
client.send(send_length)
client.send(message)
print(client.recv(2048).decode(FORMAT))
if msg == DISCONNECT_MESSAGE:
print("session closed")
client.close()
def start():
print("\n"+ f"[LISTENING] client is listening from IP: {ADDR} ")
send2server()
I have opened the port by going on windows firewall defender and selecting new inbound and outbound rules to open 5064 TCP port.
but still, the code doesn't works..
my server keeps waiting for connection and the client-side after few seconds of running gives this error:
TCP error code 10060: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
Even while my server is listening from port 5064 when I scan this port to check if the port is open or not it says closed.
How do I check if the port I have forwarded is for sure open and also how do I get this thing work?
I have tried all of this and if there is any other thing I am missing please tell. I am struggling to get this work for the past 3 days.

MQTT subscription gets lost in Bluemix container

I am using the Bluemix IoT service. My program consists of the following elements:
Publisher (Local Machine)
Subscribed (Bluemix)
Publisher (Bluemix)
Subscriber (Local Machine)
I am currently following the steps
Publisher (local machine) > Subscriber (Bluemix) > Publisher (Bluemix) > Subscriber (local machine)
The issue I am facing is the moment I try to use both the subscribers together the service unsubscribes from both the ends. If I keep only subscriber the steps work perfect. The topics I am using are as follows:
topic = "iot-2/type/mymqttdevice/id/mynewdev/evt/iotData/fmt/json"
topic2 = "iot-2/type/mymqttdevice/id/mynewdev/evt/iotFile/fmt/json"
Can someone guide what am I doing wrong here?
EDIT: Adding code
Publisher on local machine is a python file consisting of typical connect and publish method. After each publish I disconnect from the IoT service.
Subscriber code on Bluemix:
# -*- coding: utf-8 -*-
#!/usr/bin/env python
import paho.mqtt.client as mqtt
import os, json
import time
organization = "xel7"
username = ""
password = ""
#Set the variables for connecting to the iot service
broker = ""
devicename = "mynewdev"
topic = "iot-2/type/mymqttdevice/id/mynewdev/evt/iotData/fmt/json"
deviceType = "mymqttdevice"
topic2 = "iot-2/type/mymqttdevice/id/mynewdev/evt/iotFile/fmt/json"
clientID = "a:" + organization + ":appId"
broker = organization + ".messaging.internetofthings.ibmcloud.com"
mqttc = mqtt.Client(clientID)
if username is not "":
mqttc.username_pw_set(username, password=password)
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
def on_subscribe(mosq, obj, mid, granted_qos):
print("Subscribed: " + str(mid) + " " + str(granted_qos))
def on_message(client, userdata, msg):
with open('indurator.txt', 'w') as fd:
txt = (msg.payload.decode('string_escape'))
fd.write(txt)
#print txt
fd.close()
mqttc.publish(topic2,msg.payload);
mqttc.connect(host=broker, port=1883, keepalive=60)
test = mqttc.subscribe(topic,0)
mqttc.on_connect = on_connect
mqttc.on_subscribe = on_subscribe
mqttc.on_message = on_message
mqttc.loop_forever()
Subscriber code on local machine to receive file published from Bluemix subscriber:
-- coding: utf-8 --
#!/usr/bin/env python
import paho.mqtt.client as mqtt
import os, json
import time
organization = "xel7"
username = ""
password = ""
#Set the variables for connecting to the iot service
broker = ""
devicename = "mynewdev"
deviceType = "mymqttdevice"
topic = "iot-2/type/mymqttdevice/id/mynewdev/evt/iotFile/fmt/json"
clientID = "a:" + organization + ":appId"
broker = organization + ".messaging.internetofthings.ibmcloud.com"
mqttc = mqtt.Client(clientID)
if username is not "":
mqttc.username_pw_set(username, password=password)
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
def on_subscribe(mosq, obj, mid, granted_qos):
print("Subscribed: " + str(mid) + " " + str(granted_qos))
def on_message(client, userdata, msg):
with open('receivednew.txt', 'w') as fd:
txt = (msg.payload.decode('string_escape'))
fd.write(txt)
#print txt
fd.close()
mqttc.connect(host=broker, port=1883, keepalive=60)
test = mqttc.subscribe(topic,0)
mqttc.on_connect = on_connect
mqttc.on_subscribe = on_subscribe
mqttc.on_message = on_message
mqttc.loop_forever()
Glad you figured out the solution. To summarize as hardillb and amadain mentioned, the same client ID should not be used simultaneously per the Watson IoT Platform documentation.
If a client ID is being re-used, when you attempt to connect to the IoT platform, your device or application receives an error. This may indicate your disconnects are due to the clientID being re-used or “stolen”.
If you have two devices connecting with the same clientId and credentials – that leads to the clientId stealing. Only one unique connection is allowed per clientID; you can not have two concurrent connections using the same ID.
If 2 clients attempt to connect to IoT at the same time using the same client ID, a connection error occurs

Socket use in python

I want to create a chat program between two machines. I am using machine one which has the IP address 192.168.0.5, I can successfully send a message to machine two 192.168.0.2, and then send a message in response from machine two, to machine 1.
However I encountered a problem on the second send attempt from either machine, (noticing that before sending the second time I wait for a response from the initial send) claiming that the IP address is already in use or connection is refused, how can this be changed so that a defined number of choices can be sent?
I appreciate that the following code is not the most efficient way of sending and receiving multiple messages, that would be some description of for loop. For example for sendAndRecieve in range(0,5).
The two machines are linked using ethernet cables running through a switch and the code is run simultaneously.
Machine 1 code:
#Sending first message
host = "192.168.0.5"
port = 4446
from socket import *
s = socket(AF_INET, SOCK_STREAM)
s.bind((host,port))
s.listen(1)
print("listening")
q,addr = s.accept(1024)
data = "This is the first message I am sending"
data = data.encode("utf-8")
q.send(data)
s.close
#Recieving response message 1
while True:
try:
host = "192.168.0.2"
port = 4446
from socket import*
s = socket(AF_INET, SOCK_STREAM)
s.connect((host,port))
msg = s.recv(1024)
msg = msg.decode("utf-8")
print(msg)
s.close()
except:
pass
#Sending second message this is where the problem happens
host = "192.168.0.5"
port = 4446
from socket import *
s = socket(AF_INET, SOCK_STREAM)
s.bind((host,port))
s.listen(1)
print("listening")
q,addr = s.accept(1024)
data = "This is the first message I am sending"
data = data.encode("utf-8")
q.send(data)
s.close
Machine 2 code:
#Recieving message 1
while True:
try:
host = "192.168.0.5"
port = 4446
from socket import*
s = socket(AF_INET, SOCK_STREAM)
s.connect((host,port))
msg = s.recv(1024)
msg = msg.decode("utf-8")
print(msg)
s.close()
except:
pass
#Sending first message
host = "192.168.0.2"
port = 4446
from socket import *
s = socket(AF_INET, SOCK_STREAM)
s.bind((host,port))
s.listen(1)
print("listening")
q,addr = s.accept(1024)
data = "This is the first message I am sending"
data = data.encode("utf-8")
q.send(data)
s.close
#Recieving response message 1 this is where the problem happens
while True:
try:
host = "192.168.0.25"
port = 4446
from socket import*
s = socket(AF_INET, SOCK_STREAM)
s.connect((host,port))
msg = s.recv(1024)
msg = msg.decode("utf-8")
print(msg)
s.close()
except:
pass
Reading through your code, I don't see how Machine 2's while loop will ever stop trying to receive data from Machine 1 (there's no break in the loop other than if an error is encountered). Machine 1 does continue on after Machine 2 connects the first time, but then tries to connect to Machine 2 while Machine 2 is trying to connect to Machine 1. That's probably the cause of the error that you're seeing, and why you only see the first message sent/received.