Welcome to socket_protocol’s documentation!¶
socket_protocol (Socket Protocol)¶
Author:
- Dirk Alders <sudo-dirk@mount-mockery.de>
Description:
This Module supports point to point communication for client-server issues.
Submodules:
socket_protocol.data_storage
socket_protocol.pure_json_protocol
socket_protocol.struct_json_protocol
Unittest:
See also theunittest
documentation.
Module Documentation:
-
socket_protocol.
AUTH_STATE_KEY_TRANSFERRED
= 3¶ Authentification Status for ‘Key has been sent’
-
socket_protocol.
AUTH_STATE_SEED_REQUESTED
= 1¶ Authentification Status for ‘Seed was requested’
-
socket_protocol.
AUTH_STATE_SEED_TRANSFERRED
= 2¶ Authentification Status for ‘Seed has been sent’
-
socket_protocol.
AUTH_STATE_TRUSTED_CONNECTION
= 4¶ Authentification Status for a ‘Trusted Connection’
-
socket_protocol.
AUTH_STATE_UNTRUSTED_CONNECTION
= 0¶ Authentification Status for an ‘Untrusted Connection’
-
socket_protocol.
AUTH_STATE__NAMES
= {0: 'Untrusted Connection', 1: 'Seed was requested', 2: 'Seed has been sent', 3: 'Key has been sent', 4: 'Trusted Connection'}¶ Authentification Status names for previous defined authentification states
-
socket_protocol.
DID_AUTH_KEY
= 1¶ DID for authentification (key)
-
socket_protocol.
DID_AUTH_SEED
= 0¶ DID for authentification (seed)
-
socket_protocol.
DID_CHANNEL_NAME
= 0¶ DID for channel name
-
exception
socket_protocol.
RequestSidExistsError
¶
-
exception
socket_protocol.
ResponseSidExistsError
¶
-
socket_protocol.
SID_AUTH_REQUEST
= 0¶ SID for authentification request
-
socket_protocol.
SID_AUTH_RESPONSE
= 1¶ SID for authentification response
-
socket_protocol.
SID_CHANNEL_NAME_REQUEST
= 8¶ SID for channel name exchange request
-
socket_protocol.
SID_CHANNEL_NAME_RESPONSE
= 9¶ SID for channel name exchange response
-
socket_protocol.
SID_EXECUTE_REQUEST
= 30¶ SID for a execute request
-
socket_protocol.
SID_EXECUTE_RESPONSE
= 31¶ SID for a execute response
-
socket_protocol.
SID_READ_REQUEST
= 10¶ SID for a read data request
-
socket_protocol.
SID_READ_RESPONSE
= 11¶ SID for read data response
-
socket_protocol.
SID_WRITE_REQUEST
= 20¶ SID for a write data request
-
socket_protocol.
SID_WRITE_RESPONSE
= 21¶ SID for a write data response
-
socket_protocol.
STATUS_AUTH_REQUIRED
= 3¶ Status for ‘authentification is required’
-
socket_protocol.
STATUS_BUFFERING_UNHANDLED_REQUEST
= 1¶ Status for ‘unhandled request’
-
socket_protocol.
STATUS_CALLBACK_ERROR
= 2¶ Status for ‘callback errors’
-
socket_protocol.
STATUS_CHECKSUM_ERROR
= 5¶ Status for ‘checksum error’
-
socket_protocol.
STATUS_LOG_LVL
= {0: 20, 1: 30, 2: 40, 3: 30, 4: 40, 5: 40, 6: 30}¶ Status depending log level for messages
-
socket_protocol.
STATUS_OKAY
= 0¶ Status for ‘okay’
-
socket_protocol.
STATUS_OPERATION_NOT_PERMITTED
= 6¶ Status for ‘operation not permitted’
-
socket_protocol.
STATUS_SERVICE_OR_DATA_UNKNOWN
= 4¶ Status for ‘service or data unknown’
-
class
socket_protocol.
data_storage
(*args, **kwargs)¶ This is a storage object for socket_protocol messages.
Parameters: - status (int) – The message status.
- service_id (int) – The Service-ID.
- data_id (int) – The Data-ID.
- data (any) – The transfered data.
-
get_data
(default=None)¶ This Method returns the message data.
Parameters: default – The default value, if no data is available.
-
get_data_id
(default=None)¶ This Method returns the message Data-ID.
Parameters: default – The default value, if no data is available.
-
get_service_id
(default=None)¶ This Method returns the message Service-ID.
Parameters: default – The default value, if no data is available.
-
get_status
(default=None)¶ This Method returns the message status.
Parameters: default – The default value, if no data is available.
-
class
socket_protocol.
pure_json_protocol
(comm_instance, secret=None, auto_auth=False, channel_name=None)¶ This class supports to transfer a message and it’s data.
Parameters: - comm_instance (instance) – A communication instance.
- secret (str) – An optinal secret (e.g. created by
binascii.hexlify(os.urandom(24))
). - auto_auth (bool) – An optional parameter to enable (True) automatic authentification, otherwise you need to do it manually, if needed.
- channel_name (str) – An optional parameter to set a channel name for logging of the communication.
Hint
- The Service-ID is designed to identify the type of the communication (e.g.
READ_REQUEST
,WRITE_REQUEST
,READ_RESPONSE
,WRITE_RESPONSE
, …) - The Data-ID is designed to identify the requests / responses using the same Service_ID.
Note
The
comm_instance
needs to have at least the following interface:- A Method
comm_instance.init_channel_name()
to set the channel name. - A Constant
comm_instance.IS_CLIENT
to identify that thecomm_instance
is a client (True) or a server (False). - A Method
comm_instance.is_connected()
to identify if the instance is connected (True) or not (False). - A Method
comm_instance.reconnect()
to initiate a reconnect. - A Method
comm_instance.register_callback()
to register a data available callback. - A Method
comm_instance.register_connect_callback()
to register a connect callback. - A Method
comm_instance.register_disconnect_callback()
to register a disconnect callback. - A Method
comm_instance.send()
to send data via thecomm_instance
.
Note
The parameter
auto_auth
is only relevant, if a secret is given and thecomm_instance
is a client. The authentification is initiated directly after the connection is established.Note
The
channel_name
-exchange will be initiated by the client directly after the the connection is established.- If a channel_name is given at both communication sides and they are different, the client name is taken over and the server will log a warning message.
Example:
import sys sys.path.append('../..') import report import socket_protocol from socket_protocol_server import example_protocol, DID_ASC_TIME import tcp_socket import time if __name__ == '__main__': report.stdoutLoggingConfigure(log_name_lvl=[('root', 'INFO'), ]) c = tcp_socket.tcp_client_stp('127.0.0.1', 17017) sp = example_protocol(c, channel_name='example_client') sp.send(socket_protocol.SID_READ_REQUEST, DID_ASC_TIME, None) print('The Client received: %s' % repr(sp.receive(socket_protocol.SID_READ_RESPONSE, 0).get_data()))
and
import sys sys.path.append('../..') import report import socket_protocol import tcp_socket import time DID_ASC_TIME = 0 class example_protocol(socket_protocol.pure_json_protocol): def __init__(self, *args, **kwargs): socket_protocol.pure_json_protocol.__init__(self, *args, **kwargs) # self.add_data((socket_protocol.SID_READ_REQUEST, socket_protocol.SID_READ_RESPONSE), DID_ASC_TIME, 'asc_time') # if not self.__comm_inst__.IS_CLIENT: self.register_callback(socket_protocol.SID_READ_REQUEST, 0, self.time_callback) def time_callback(self, msg): if msg.get_status() == socket_protocol.STATUS_OKAY: return socket_protocol.STATUS_OKAY, time.asctime() else: return socket_protocol.STATUS_OPERATION_NOT_PERMITTED, None if __name__ == '__main__': report.stdoutLoggingConfigure(log_name_lvl=[('root', 'INFO'), ]) s = tcp_socket.tcp_server_stp('127.0.0.1', 17017) sp = example_protocol(s, channel_name='example_server') i = 0 while not s.is_connected() and i <= 20: i += 1 time.sleep(.1) # wait for a connection i = 0 while s.is_connected() and i <= 20: i += 1 time.sleep(.1) # wait for disconnect
Will result to the following output:
2021-01-12 09:13:30,657: root.socket_protocol.example_client - INFO - prot-client: Resetting authentification state to AUTH_STATE_UNTRUSTED_CONNECTION 2021-01-12 09:13:30,657: root.socket_protocol - INFO - prot-client: Initialisation finished. 2021-01-12 09:13:30,657: root.socket_protocol.example_client - INFO - prot-client: TX -> service: read data request, data_id: asc_time, status: okay, data: "None" 2021-01-12 09:13:30,708: root.tcp_socket.example_client - INFO - comm-client: Connection established... (to 127.0.0.1:17017) 2021-01-12 09:13:30,708: root.socket_protocol.example_client - INFO - prot-client: TX -> service: channel name request, data_id: name, status: okay, data: "'example_client'" 2021-01-12 09:13:30,708: root.tcp_socket.example_client - INFO - comm-client: TX -> "(74): 7b 22 64 61 74 61 5f 69 64 22 3a 20 30 2c 20 22 73 65 72 76 69 63 65 5f 69 64 22 3a 20 38 2c 20 22 73 74 61 74 75 73 22 3a 20 30 2c 20 22 64 61 74 61 22 3a 20 22 65 78 61 6d 70 6c 65 5f 63 6c 69 65 6e 74 22 7d f5 cd dd e7" 2021-01-12 09:13:30,758: root.tcp_socket.example_client - INFO - comm-client: TX -> "(63): 7b 22 64 61 74 61 5f 69 64 22 3a 20 30 2c 20 22 73 65 72 76 69 63 65 5f 69 64 22 3a 20 31 30 2c 20 22 73 74 61 74 75 73 22 3a 20 30 2c 20 22 64 61 74 61 22 3a 20 6e 75 6c 6c 7d 45 05 7b b4" 2021-01-12 09:13:30,759: root.stringtools.stp - INFO - STP: message identified - (62): 7b 22 64 61 74 61 5f 69 64 22 3a 20 30 2c 20 22 73 65 72 76 69 63 65 5f 69 64 22 3a 20 39 2c 20 22 73 74 61 74 75 73 22 3a 20 30 2c 20 22 64 61 74 61 22 3a 20 6e 75 6c 6c 7d 30 59 be 2f 2021-01-12 09:13:30,760: root.tcp_socket.example_client - INFO - comm-client: RX <- "(62): 7b 22 64 61 74 61 5f 69 64 22 3a 20 30 2c 20 22 73 65 72 76 69 63 65 5f 69 64 22 3a 20 39 2c 20 22 73 74 61 74 75 73 22 3a 20 30 2c 20 22 64 61 74 61 22 3a 20 6e 75 6c 6c 7d 30 59 be 2f" 2021-01-12 09:13:30,760: root.socket_protocol.example_client - INFO - prot-client: RX <- service: channel name response, data_id: name, status: okay, data: "None" 2021-01-12 09:13:30,811: root.stringtools.stp - INFO - STP: message identified - (85): 7b 22 64 61 74 61 5f 69 64 22 3a 20 30 2c 20 22 73 65 72 76 69 63 65 5f 69 64 22 3a 20 31 31 2c 20 22 73 74 61 74 75 73 22 3a 20 30 2c 20 22 64 61 74 61 22 3a 20 22 54 75 65 20 4a 61 6e 20 31 32 20 30 39 3a 31 33 3a 33 30 20 32 30 32 31 22 7d 2b b5 b2 77 2021-01-12 09:13:30,812: root.tcp_socket.example_client - INFO - comm-client: RX <- "(85): 7b 22 64 61 74 61 5f 69 64 22 3a 20 30 2c 20 22 73 65 72 76 69 63 65 5f 69 64 22 3a 20 31 31 2c 20 22 73 74 61 74 75 73 22 3a 20 30 2c 20 22 64 61 74 61 22 3a 20 22 54 75 65 20 4a 61 6e 20 31 32 20 30 39 3a 31 33 3a 33 30 20 32 30 32 31 22 7d 2b b5 b2 77" 2021-01-12 09:13:30,812: root.socket_protocol.example_client - INFO - prot-client: RX <- service: read data response, data_id: asc_time, status: okay, data: "'Tue Jan 12 09:13:30 2021'" The Client received: 'Tue Jan 12 09:13:30 2021'
-
add_data
(service_id, data_id, name)¶ Method to add a name for a specific message.
Parameters: - service_id (int or list of ints) – The Service-ID of the message. See class definitions starting with
SID_
. - data_id (int) – The Data-ID of the message.
- name (str) – The Name for the transfered message.
- service_id (int or list of ints) – The Service-ID of the message. See class definitions starting with
-
add_msg_to_auth_whitelist_
(service_id, data_id)¶ Method to add a specific message to the list, where no authentification is required.
Parameters: - service_id (int) – The Service-ID of the message. See class definitions starting with
SID_
. - data_id (int) – The Data-ID of the message.
- service_id (int) – The Service-ID of the message. See class definitions starting with
-
add_service
(req_sid, resp_sid, req_name=None, resp_name=None)¶ Method to add a Service defined by Request- and Response Serivce-ID.
Parameters: - req_sid (int) – The Request Service-ID.
- resp_sid (int) – The Response Service-ID.
-
add_status
(status, name)¶ Method to add a name for a status.
Parameters: - status (int) – The Status. See class definitions starting with
STATUS_
. - name (str) – The Name for the Status.
- status (int) – The Status. See class definitions starting with
-
authentificate
(timeout=2)¶ This method authetificates the client at the server.
Parameters: timeout (float) – The timeout for the authentification (requesting seed, sending key and getting authentification_feedback). Returns: True, if authentification was successfull; False, if not. Return type: bool Note
An authentification will only processed, if a secret had been given on initialisation.
Note
Client and Server needs to use the same secret.
-
check_authentification_state
()¶ This Method return the Authitification State as boolean value.
Returns: True, if authentification state is okay, otherwise False Return type: bool
-
connection_established
()¶ This Method returns the Connection state including authentification as a boolean value.
Returns: True, if the connection is established (incl. authentification, if a secret has been given) Return type: bool
-
is_connected
()¶ This Methods returns Connection state of the Communication Instance
comm_instance.is_connected()
.Returns: True if the comm_instance
is connected, otherwise False..Return type: bool
-
receive
(service_id, data_id, timeout=1)¶ This Method returns a message object for a defined message or None, if this message is not available after the given timout.
Parameters: - service_id (int) – The Service-ID for the message. See class definitions starting with
SID_
. - data_id (int) – The Data-ID for the message.
- timeout (float) – The timeout for receiving.
Returns: The received data storage object or None, if no data was received.
Return type: - service_id (int) – The Service-ID for the message. See class definitions starting with
-
reconnect
()¶ This methods initiates a reconnect by calling
comm_instance.reconnect()
.
-
register_callback
(service_id, data_id, callback, *args, **kwargs)¶ This method registers a callback for the given parameters. Giving
None
means, that all Service-IDs or all Data-IDs are used. If a message hitting these parameters has been received, the callback will be executed.Parameters: - service_id (int) – The Service-ID for the message. See class definitions starting with
SID_
. - data_id (int) – The Data-ID for the message.
Note
The
callback()
is priorised in the following order:- Callbacks with defined Service-ID and Data-ID.
- Callbacks with a defined Service-ID and all Data-IDs.
- Callbacks with a defined Data-ID and all Service-IDs.
- Unspecific Callbacks.
Note
The
callback()
is executed with these arguments:Parameters given at the callback call:
- The first Arguments is the received message as
data_storage
object. - Further arguments given at registration.
- Further keyword arguments given at registration.
Return value of the callback:
If the Callback is a Request Callback for a registered Service, the return value has to be a tuple or list with
response_status
: The response status (see class definitions starting withSTA_*
.response_data
: A JSON iterable object to be used as data for the response.
Note
Only registered services will respond via the callbacks return values with the same data_id.
- service_id (int) – The Service-ID for the message. See class definitions starting with
-
send
(service_id, data_id, data, status=0, timeout=2)¶ This methods sends out a message with the given content.
Parameters: - service_id (int) – The Service-ID for the message. See class definitions starting with
SERVICE_
. - data_id (int) – The Data-ID for the message.
- data (str) – The data to be transfered. The data needs to be json compatible.
- status (int) – The Status for the message. All requests should have
STATUS_OKAY
. - timeout (float) – The timeout for sending data (e.g. time to establish new connection).
Returns: True if data had been sent, otherwise False.
Return type: bool
- service_id (int) – The Service-ID for the message. See class definitions starting with
-
class
socket_protocol.
struct_json_protocol
(*args, **kwargs)¶ This Class has the same functionality like
pure_json_protocol
. The message length is less than forpure_json_protocol
, but the functionality and compatibility is reduced. See also parentpure_json_protocol
.Note
This class is depreceated and here for compatibility reasons (to support old clients or servers). Usage of
pure_json_protocol
is recommended.