Add Sockets To Django View For Contact With Robot

Viewed 114

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)
0 Answers
Related