I am trying to give commands to a robot from a Django site through sockets as this has been recommended as the best possible way to do it. I have been working with Django and sockets in isolation but I have not been able to find an applicable tutorial(only chat apps) on how to integrate the two. If anybody has any experience with this and knows how to add this to my view any help would be great. (I just need help with the server-side of it, I know how to setup the client)
EDIT:
I have tried to override the form_valid of the RobotDetail view, however I am getting an error saying that the connection is refused
when I run the client side. Any help would be great.
conn.send("MSG Received".encode(FORMAT))
BrokenPipeError: [Errno 32] Broken pipe
conn.send("MSG Received".encode(FORMAT))
BrokenPipeError: [Errno 32] Broken pipe
My Model:
class Robot(models.Model):
def fetch_choices():
scope = [REDACTED]
creds = ServiceAccountCredentials.from_json_keyfile_name("dashboard/Files/creds.json", scope)
client = gspread.authorize(creds)
sheet = client.open("tutorial").sheet1
path_names = []
path_name_fetch = sheet.col_values(1)
for i in path_name_fetch:
if (i, i) not in path_names:
path_names.append((i, i))
return path_names
name = models.CharField(max_length=200)
path_options = models.CharField(choices=fetch_choices(), default=fetch_choices(), max_length=100)
status_choices = [('waiting', 'waiting'), ('running', 'running'), ('stuck', 'stuck')]
current_status = models.CharField(choices=status_choices, default=status_choices[0], max_length=100)
def __str__(self):
return self.name + ' | Current Status: ' + self.current_status
def get_absolute_url(self):
return reverse('dashboard-home')
My Form:
class RobotDetail(UpdateView):
model = Robot
form_class = RobotUpdateForm
template_name = 'dashboard/robotdetail.html'
My Template:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Dashboard</title>
</head>
<body>
{% extends 'theblog/base.html' %}
{% block content %}
<h1>Dispatcher</h1>
<form method="POST">
{% csrf_token %}
{{ form.as_p}}
<button class="btn btn-secondary">Dispatch</button>
</form>
{% endblock %}
</body>
</html>
My View:
HEADER = 64
PORT = 6060
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT!"
class RobotDetail(UpdateView):
model = Robot
form_class = RobotUpdateForm
template_name = 'dashboard/robotdetail.html'
def form_valid(self, form):
self.object = form.save()
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
def handle_client(conn, addr):
print(f"[NEW CONNECTION] {addr} connected")
connected = True
while connected:
msg_length = conn.recv(HEADER).decode(FORMAT)
if msg_length:
msg_length = int(msg_length)
msg = conn.recv(msg_length).decode(FORMAT)
if msg == DISCONNECT_MESSAGE:
connected = False
print(f"[{ADDR}] {msg}")
conn.send("MSG Received".encode(FORMAT))
conn.close()
def start():
server.listen()
print(f"[LISTENING] Server Is Listening On {SERVER}")
while True:
conn, addr = server.accept()
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")
print("[Starting] Server")
start()
Client Side Code:
import socket
HEADER = 64
PORT = 6060
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT!"
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)
def send(msg):
message = msg.encode(FORMAT)
msg_length = len(message)
send_length = str(msg_length).encode(FORMAT)
send_length += b' ' * (HEADER - len(send_length))
client.send(send_length)
client.send(message)
send("Hello World!")
send("Hello Andrew")
send("Hello")
send(DISCONNECT_MESSAGE)