85 lines
2.5 KiB
Python
85 lines
2.5 KiB
Python
from abc import ABCMeta
|
|
|
|
import zmq
|
|
|
|
from robot_interface.core.config import settings
|
|
|
|
|
|
class SocketBase(object):
|
|
"""
|
|
Base class for endpoints associated with a ZeroMQ socket.
|
|
|
|
:ivar identifier: The identifier of the endpoint.
|
|
:vartype identifier: str
|
|
|
|
:ivar port: The port used by the socket, set by `create_socket`.
|
|
:vartype port: int | None
|
|
|
|
:ivar socket: The ZeroMQ socket object, set by `create_socket`.
|
|
:vartype socket: zmq.Socket | None
|
|
|
|
:ivar bound: Whether the socket is bound or connected, set by `create_socket`.
|
|
:vartype bound: bool | None
|
|
"""
|
|
__metaclass__ = ABCMeta
|
|
|
|
name = None
|
|
socket = None
|
|
|
|
def __init__(self, identifier):
|
|
self.identifier = identifier
|
|
self.port = None # Set later by `create_socket`
|
|
self.socket = None # Set later by `create_socket`
|
|
self.bound = None # Set later by `create_socket`
|
|
|
|
def create_socket(self, zmq_context, socket_type, port, options=[], bind=True):
|
|
"""
|
|
Create a ZeroMQ socket.
|
|
|
|
:param zmq_context: The ZeroMQ context to use.
|
|
:type zmq_context: zmq.Context
|
|
|
|
:param socket_type: The type of socket to create. Use zmq constants, e.g. zmq.SUB or zmq.REP.
|
|
:type socket_type: int
|
|
|
|
:param port: The port to use.
|
|
:type port: int
|
|
|
|
:param options: A list of tuples where the first element contains the option and the second the value.
|
|
:type options: list[tuple[int, int]]
|
|
|
|
:param bind: Whether to bind the socket or connect to it.
|
|
:type bind: bool
|
|
"""
|
|
self.port = port
|
|
self.socket = zmq_context.socket(socket_type)
|
|
|
|
for option, arg in options:
|
|
self.socket.setsockopt(option,arg)
|
|
|
|
self.bound = bind
|
|
if bind:
|
|
self.socket.bind("tcp://*:{}".format(port))
|
|
else:
|
|
self.socket.connect("tcp://{}:{}".format(settings.agent_settings.control_backend_host, port))
|
|
|
|
def close(self):
|
|
"""Close the ZeroMQ socket."""
|
|
if not self.socket: return
|
|
self.socket.close()
|
|
self.socket = None
|
|
|
|
def endpoint_description(self):
|
|
"""
|
|
Description of the endpoint. Used for negotiation.
|
|
|
|
:return: A dictionary with the following keys: id, port, bind. See API specification at:
|
|
https://utrechtuniversity.youtrack.cloud/articles/N25B-A-14/RI-CB-Communication#negotiation
|
|
:rtype: dict
|
|
"""
|
|
return {
|
|
"id": self.identifier,
|
|
"port": self.port,
|
|
"bind": not self.bound
|
|
}
|