hisock.server#

A module containing the main server classes and functions, including HiSockServer and start_server()

Note

Header lengths shouldn’t be too long. By default, the header length is 16 bytes. This is good enough for most applications, as allows for 10**16 bytes to be sent.

class hisock.server.HiSockServer(addr: tuple[str, int], max_connections: int = 0, header_len: int = 16, cache_size: int = -1, keepalive: bool = True)#

The server class for HiSock.

Parameters:
  • addr (tuple) – A two-element tuple, containing the IP address and the port number of where the server should be hosted. Due to the nature of reserved ports, it is recommended to host the server with a port number that’s greater than or equal to 1024. Only IPv4 is currently supported.

  • max_connections (int, optional) – The number of maximum connections the server should accept before refusing client connections. Pass in 0 for unlimited connections. Default passed in by start_server() is 0.

  • header_len (int, optional) – An integer, defining the header length of every message. A larger header length would mean a larger maximum message length (about 10**header_len). Any client connecting MUST have the same header length as the server, or else it will crash. Default passed in by start_server() is 16 (maximum length: 10 quadrillion bytes).

  • cache_size (int, optional) – The size of the message cache. -1 or below for no message cache, 0 for an unlimited cache size, and any other number for the cache size.

  • keepalive (bool, optional) – A bool indicating whether a keepalive signal should be sent or not. If this is True, then a signal will be sent to every client every minute to prevent hanging clients in the server. The clients have thirty seconds to send back an acknowledge signal to show that they are still alive. Default is True.

Variables:
  • addr (tuple) – A two-element tuple containing the IP address and the port.

  • header_len (int) – An integer storing the header length of each “message”.

  • clients (dict) – A dictionary with the socket as its key and the client info as its value.

  • clients_rev (dict) – A dictionary with the client info as its key and the socket as its value (for reverse lookup, up-to-date with clients).

  • funcs (dict) – A list of functions registered with decorator on(). This is mainly used for under-the-hood-code.

Raises:

TypeError – If the address is not a tuple.

close()#

Closes the server; ALL clients will be disconnected, then the server socket will be closed.

Running server.run() won’t do anything now.

disconnect_all_clients(force=False)#

Disconnect all clients.

disconnect_client(client: str | Tuple[str, int] | ClientInfo, force: bool = False, call_func: bool = False)#

Disconnects a specific client.

Parameters:
  • client (Client) – The client to send data to. The format could be either by IP+port, a client name, or a ClientInfo instance.

  • force (bool, optional) – A boolean, specifying whether to force a disconnection or not. Defaults to False.

  • call_func – A boolean, specifying whether to call the leave reserved function when client is disconnected. Defaults to False.

Raises:
  • ValueError – If the client format is wrong.

  • ClientNotFound – If the client does not exist.

  • UserWarning – Using client name, and more than one client with the same name is detected.

get_addr() tuple[str, int]#

Gets the address of where the HiSock server is serving at.

Returns:

A tuple of the address in the form of (ip, port)

Return type:

tuple[str, int]

get_all_clients(key: Callable | str = None) list[dict[str, str]]#

Get all clients currently connected to the server. This is recommended over the class attribute self._clients or self.clients_rev, as it is in a dictionary-like format.

Parameters:

key (Union[Callable, str], optional) – If specified, there are two outcomes: If it is a string, it will search for the dictionary for the key, and output it to a list (currently supports “ip”, “name”, “group”). If it is a callable, it will try to integrate the callable into the output with the filter() function.

Returns:

A list of dictionaries, with the clients

Return type:

list[dict, …]

get_client(client: str | tuple[str, int]) dict[str, str | socket.socket]#

Gets the client data for a client from a name or tuple in the form of (ip, port).

Returns:

The client data without the socket.

Return type:

dict

Raises:
  • ValueError – Client format is wrong.

  • ClientNotFound – Client does not exist.

  • UserWarning – Using client name, and more than one client with the same name is detected.

get_group(group: str) list[dict[str, str | socket.socket]]#

Gets all clients from a specific group.

Note

If you want to get them from clients_rev directly, use _get_all_client_sockets_in_group() instead.

Parameters:

group (str) – A string, representing the group to look up

Raises:

GroupNotFound – Group does not exist

Returns:

A list of dictionaries of clients in that group, containing the address, name, group, and socket

Return type:

list

on(command: str, threaded: bool = False, override: bool = False) Callable#

A decorator that adds a function that gets called when the server receives a matching command.

Reserved functions are functions that get activated on specific events, and they are:

  1. join - Activated when a client connects to the server

  2. leave - Activated when a client disconnects from the server

  3. message - Activated when a client messages to the server

  4. name_change - Activated when a client changes its name

  5. group_change - Activated when a client changes its group

The parameters of the function depend on the command to listen. For example, reserved commands join and leave have only one client parameter passed, while reserved command message has two: client data and message. Other unreserved functions will also be passed in the same parameters as message.

In addition, certain type casting is available to both reserved and unreserved functions. That means, that, using type hints, you can automatically convert between needed instances. The type casting currently supports:

  • bytes

  • str

  • int

  • float

  • bool

  • None

  • list (with the types listed here)

  • dict (with the types listed here)

For more information, read the documentation for type casting.

Parameters:
  • command (str) – A string, representing the command the function should activate when receiving it.

  • threaded (bool, optional) – A boolean, representing if the function should be run in a thread in order to not block the run loop. Default is False.

  • override (bool, optional) – A boolean representing if the function should override the reserved function with the same name and to treat it as an unreserved function. Default is False.

Returns:

The same function (the decorator just appended the function to a stack).

Return type:

function

Raises:

TypeError – If the number of function arguments is invalid.

send_all_clients(command: str, content: bytes | str | int | float | None | ClientInfo | List[str | int | float | bool | None | dict | list] | Dict[str, str | int | float | bool | None | dict | list] = None)#

Sends the command and content to ALL clients connected.

Parameters:
  • command (str) – A string, representing the command to send to every client.

  • content (Sendable, optional) – The message / content to send

send_client(client: str | Tuple[str, int] | ClientInfo, command: str, content: bytes | str | int | float | None | ClientInfo | List[str | int | float | bool | None | dict | list] | Dict[str, str | int | float | bool | None | dict | list] = None)#

Sends data to a specific client.

Parameters:
  • client (Client) – The client to send data to. The format could be either by IP+port, or a client name.

  • command (str) – A string, containing the command to send.

  • content (Sendable) – The message / content to send

Raises:
  • ValueError – Client format is wrong.

  • ClientNotFound – Client does not exist.

  • UserWarning – Using client name, and more than one client with the same name is detected.

send_group(group: str | ClientInfo, command: str, content: bytes | str | int | float | None | ClientInfo | List[str | int | float | bool | None | dict | list] | Dict[str, str | int | float | bool | None | dict | list] = None)#

Sends data to a specific group. Groups are recommended for more complicated servers or multipurpose servers, as it allows clients to be divided, which allows clients to be sent different data for different purposes.

Parameters:
  • group (Union[str, ClientInfo]) – A string or a ClientInfo, representing the group to send data to. If the group is a ClientInfo, and the client is in a group, the method will send data to that group.

  • command (str) – A string, containing the command to send

  • content (Union[bytes, dict]) – A bytes-like object, with the content/message to send

Raises:

TypeError – If the group does not exist, or the client is not in a group (ClientInfo).

start(callback: Callable | None = None, error_handler: Callable | None = None)#

Start the main loop for the server.

Parameters:
  • callback (Callable, optional) – A function that will be called every time the client receives and handles a message.

  • error_handler (Callable, optional) – A function that will be called every time the client encounters an error.


class hisock.server.ThreadedHiSockServer(*args, **kwargs)#

HiSockClient, but running in its own thread as to not block the main loop. Please note that while this is running in its own thread, the event handlers will still be running in the main thread. To avoid this, use the threaded=True argument for the on decorator.

For documentation purposes, see HiSockClient.

start(callback: Callable | None = None, error_handler: Callable | None = None)#

Starts the main server loop. For documentation, see HiSockServer.start().

close()#

Closes the server. Blocks the thread until the server is closed. For documentation, see HiSockServer.close().


hisock.server.start_server(addr, max_connections=0, header_len=16)#

Creates a HiSockServer instance. See HiSockServer for more details and documentation.

Returns:

A HiSockServer instance.

hisock.server.start_threaded_server(*args, **kwargs)#

Creates a ThreadedHiSockServer instance. See ThreadedHiSockServer for more details. For documentation, see start_server().

Returns:

A ThreadedHiSockServer instance