Skip to content

feat: add support for unix sockets to TCPTransport in erpc_python #437

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from

Conversation

brussee
Copy link

@brussee brussee commented Nov 2, 2024

  • feat: add support for unix sockets to TCPTransport in erpc_python
  • chore: organize imports

@brussee brussee force-pushed the feat-tcp-transport-unix branch 3 times, most recently from abd1d03 to 72663f0 Compare November 2, 2024 00:41
@JanKomarekNXP
Copy link
Contributor

Hi, we reviewed your PR and really like the idea of adding a UNIX socket to the transport layers. After discussing with @MichalPrincNXP, we concluded that since UNIX sockets do not use TCP, it would be more appropriate to create a new transport layer.

Below is the code that incorporates your changes into a new UnixSocketTransport layer. Could you please test it and update the PR accordingly?

Note that the code has been slightly modified, as we are also preparing an update to the Python implementation.

# Import
from typing import Optional

# Transport
class UnixSocketTransport(FramedTransport):
    def __init__(self, unix_socket: str, is_server: bool):
        super(UnixSocketTransport, self).__init__()
        self._unix_socket = unix_socket
        self._is_server = is_server
        self._sock: Optional[socket.socket] = None

        if self._is_server:
            self._server_thread = threading.Thread(target=self._serve)
            self._server_thread.daemon = True
            self._server_thread.start()
            self._server_sock_event_start = threading.Event()
        else:
            self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            self._sock.connect(self._unix_socket)

    def _serve(self):
        s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        s.setblocking(True)
        s.bind(self._unix_socket)

        while True:
            self._sock, _ = s.accept()
            self._server_sock_event_start.set()

    def close(self):
        if self._is_server:
            self._server_sock_event_start.clear()

        if self._sock:
            self._sock.shutdown(socket.SHUT_RDWR)
            self._sock.close()
            self._sock = None

    def _base_send(self, data: bytes):
        if self._is_server:
            self._server_sock_event_start.wait()
        if self._sock:
            self._sock.sendall(data)

    def _base_receive(self, count: int) -> bytes:
        if self._is_server:
            self._server_sock_event_start.wait()

        if self._sock:
            remaining = count
            result = bytes()
            while remaining:
                data = self._sock.recv(remaining)
                if len(data) == 0:
                    self.close()
                    raise ConnectionClosed()
                result += data
                remaining -= len(data)
            return result

        return bytes()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants