whisker.qtclient
whisker/qtclient.py
Copyright © 2011-2020 Rudolf Cardinal (rudolf@pobox.com).
This file is part of the Whisker Python client library.
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Multithreaded framework for Whisker Python clients using Qt.
Created: late 2016
Last update: 20 Sep 2018
Note funny bug: data sometimes sent twice.
Looks like it might be this: http://www.qtcentre.org/threads/29462-QTcpSocket-sends-data-twice-with-flush()
Attempted solution:
change
QTcpSocket()
toQTcpSocket(parent=self)
, in case the socket wasn’t getting moved between threads properly – didn’t fixdisable
flush()
– didn’t fix.send function is only being called once, according to log
adding thread ID information to the log shows that
whisker_controller
events are coming from two threads…
Anyway, bug was this:
Source:
- class whisker.qtclient.WhiskerController(server: str, parent: SimpleClass | None = None, connect_timeout_ms: int = 5000, read_timeout_ms: int = 500, name: str = 'whisker_controller', sysevent_prefix: str = 'sys_', **kwargs)[source]
Controls the Whisker immediate socket.
Encapsulates the Whisker API.
Lives in Whisker thread (B) (see
WhiskerOwner
).Emits signals that can be processed by the Whisker task (derived from
WhiskerQtTask
).
Signals:
finished()
connected()
disconnected()
message_received(str, arrow.Arrow, int)
event_received(str, arrow.Arrow, int)
key_event_received(str, arrow.Arrow, int)
client_message_received(int, str, arrow.Arrow, int)
warning_received(str, arrow.Arrow, int)
syntax_error_received(str, arrow.Arrow, int)
error_received(str, arrow.Arrow, int)
pingack_received(arrow.Arrow, int)
- Parameters:
server – host name or IP address of Whisker server
parent – optional parent :QObject
connect_timeout_ms – time to wait for successful connection (ms) before considering it a failure
read_timeout_ms – time to wait for each read (primary effect is to determine the application’s responsivity when asked to finish; see
WhiskerMainSocketListener
)name – (name for
StatusMixin
)sysevent_prefix – default system event prefix (for
WhiskerController
)kwargs – parameters to superclass
- class whisker.qtclient.WhiskerMainSocketListener(server: str, port: int, parent: SimpleClass | None = None, connect_timeout_ms: int = 5000, read_timeout_ms: int = 100, name: str = 'whisker_mainsocket', **kwargs)[source]
Whisker thread (A) (see
WhiskerOwner
). Listens to the main socket.Signals:
finished()
disconnected()
line_received(msg: str, timestamp: arrow.Arrow)
- Parameters:
server – host name or IP address of Whisker server
port – main port number for Whisker server
parent – optional parent :QObject
connect_timeout_ms – time to wait for successful connection (ms) before considering it a failure
read_timeout_ms – time to wait for each read (primary effect is to determine the application’s responsivity when asked to finish; see
WhiskerMainSocketListener
)name – (name for
StatusMixin
)kwargs – parameters to superclass
- class whisker.qtclient.WhiskerOwner(task: WhiskerQtTask, server: str, main_port: int = 3233, parent: SimpleClass | None = None, connect_timeout_ms: int = 5000, read_timeout_ms: int = 500, name: str = 'whisker_owner', sysevent_prefix: str = 'sys_', **kwargs)[source]
Object to own and manage communication with a Whisker server.
This object is owned by the GUI thread. It devolves work to two other threads:
main socket listener (
WhiskerMainSocketListener
, as the instanceself.mainsock
, in the threadself.mainsockthread
);task (
WhiskerQtTask
, as the instanceself.task
in the threadself.taskthread
) + immediate socket blocking handler (WhiskerController
, as the instanceself.controller
in the threadself.taskthread
).
References to “main” here just refers to the main socket (as opposed to the immediate socket), not the thread that’s doing most of the processing.
Signals of relevance to users:
connected()
disconnected()
finished()
message_received(str, arrow.Arrow, int)
event_received(str, arrow.Arrow, int)
pingack_received(arrow.Arrow, int)
- Parameters:
task – instance of something derived from
WhiskerQtTask
server – host name or IP address of Whisker server
main_port – main port number for Whisker server
parent – optional parent :QObject
connect_timeout_ms – time to wait for successful connection (ms) before considering it a failure
read_timeout_ms – time to wait for each read (primary effect is to determine the application’s responsivity when asked to finish; see
WhiskerMainSocketListener
)name – (name for
StatusMixin
)sysevent_prefix – default system event prefix (for
WhiskerController
)kwargs – parameters to superclass
- class whisker.qtclient.WhiskerQtTask(parent: SimpleClass | None = None, name: str = 'whisker_task', **kwargs)[source]
Base class for building a Whisker task itself. You should derive from this.
Lives in Whisker thread (B) (see
WhiskerOwner
).
Signals:
finished()
- Parameters:
parent – optional parent :QObject
name – (name for
StatusMixin
)kwargs – parameters to superclass
- on_connect() None [source]
The
WhiskerOwner
makes this slot get called when theWhiskerController
is connected.You should override this.
- set_controller(controller: WhiskerController) None [source]
Called by
WhiskerOwner
. No need to override.
- whisker.qtclient.disable_nagle(socket: <MagicMock id='139817539388464'>) None [source]
Disable the Nagle algorithm on the Qt socket. (This makes it send any outbound data immediately, rather than waiting and packaging it up with potential subsequent data. So this function chooses a low-latency mode over a high-efficiency mode.)
- whisker.qtclient.get_socket_error(socket: <MagicMock id='139817539388464'>) str [source]
Returns a textual description of the last error on the specified Qt socket.