15 #include "pStatReader.h" 16 #include "pStatServer.h" 17 #include "pStatMonitor.h" 19 #include "pStatClientControlMessage.h" 20 #include "pStatServerControlMessage.h" 21 #include "pStatFrameData.h" 22 #include "pStatProperties.h" 24 #include "datagramIterator.h" 25 #include "connectionManager.h" 47 _monitor->set_client_data(_client_data);
84 _tcp_connection = tcp_connection;
88 _udp_connection = _manager->open_UDP_connection(_udp_port);
89 while (_udp_connection.is_null()) {
92 _udp_connection = _manager->open_UDP_connection(_udp_port);
109 _client_data->_is_alive =
false;
110 _monitor->lost_connection();
111 _client_data.clear();
115 _tcp_connection.clear();
116 _udp_connection.clear();
127 dequeue_frame_data();
148 if (_hostname.empty()) {
150 if (_hostname.empty()) {
151 _hostname =
"unknown";
165 message._type = PStatServerControlMessage::T_hello;
166 message._server_hostname = get_hostname();
167 message._server_progname = _monitor->get_monitor_name();
168 message._udp_port = _udp_port;
172 _writer.
send(datagram, _tcp_connection);
183 Connection *connection = datagram.get_connection();
185 if (connection == _tcp_connection) {
187 if (message.
decode(datagram, _client_data)) {
188 handle_client_control_message(message);
190 }
else if (message._type == PStatClientControlMessage::T_datagram) {
191 handle_client_udp_data(datagram);
194 nout <<
"Got unexpected message from client.\n";
197 }
else if (connection == _udp_connection) {
198 handle_client_udp_data(datagram);
201 nout <<
"Got datagram from unexpected socket.\n";
213 switch (message._type) {
214 case PStatClientControlMessage::T_hello:
216 _client_data->set_version(message._major_version, message._minor_version);
217 int server_major_version = get_current_pstat_major_version();
218 int server_minor_version = get_current_pstat_minor_version();
220 if (message._major_version != server_major_version ||
221 (message._major_version == server_major_version &&
222 message._minor_version > server_minor_version)) {
223 _monitor->bad_version(message._client_hostname, message._client_progname,
224 message._major_version, message._minor_version,
225 server_major_version, server_minor_version);
228 _monitor->hello_from(message._client_hostname, message._client_progname);
233 case PStatClientControlMessage::T_define_collectors:
235 for (
int i = 0; i < (int)message._collectors.size(); i++) {
236 _client_data->add_collector(message._collectors[i]);
237 _monitor->new_collector(message._collectors[i]->_index);
242 case PStatClientControlMessage::T_define_threads:
244 for (
int i = 0; i < (int)message._names.size(); i++) {
245 int thread_index = message._first_thread_index + i;
246 string name = message._names[i];
247 _client_data->define_thread(thread_index, name);
248 _monitor->new_thread(thread_index);
254 nout <<
"Invalid control message received from client.\n";
266 handle_client_udp_data(
const Datagram &datagram) {
267 if (!_monitor->is_client_known()) {
277 if (_client_data->is_at_least(2, 1)) {
280 nassertv(initial_byte == 0);
283 if (!_queued_frame_data.
full()) {
304 dequeue_frame_data() {
305 while (!_queued_frame_data.
empty()) {
306 const FrameData &data = _queued_frame_data.
front();
310 int num_levels = data._frame_data->get_num_levels();
311 for (
int i = 0; i < num_levels; i++) {
312 int collector_index = data._frame_data->get_level_collector(i);
313 if (!_client_data->get_collector_has_level(collector_index, data._thread_index)) {
316 _client_data->set_collector_has_level(collector_index, data._thread_index,
true);
317 _monitor->new_collector(collector_index);
321 _client_data->record_new_frame(data._thread_index,
324 _monitor->new_data(data._thread_index, data._frame_number);
PStatMonitor * get_monitor()
Returns the monitor that this reader serves.
void encode(Datagram &datagram) const
Writes the message into the indicated datagram.
void push_back(const Thing &t)
Adds an item to the end of the buffer.
A specific kind of Datagram, especially for sending across or receiving from a network.
bool send(const Datagram &datagram, const PT(Connection) &connection, bool block=false)
Enqueues a datagram for transmittal on the indicated socket.
void set_tcp_header_size(int tcp_header_size)
Sets the header size of TCP packets.
void set_tcp_connection(Connection *tcp_connection)
This is intended to be called only once, immediately after construction, by the PStatListener that cr...
bool empty() const
Returns true if the buffer is empty.
This kind of message is sent from the server to the client on the TCP socket to establish critical co...
The data associated with a particular client, but not with any one particular frame or thread: the li...
This kind of message is sent from the client to the server on the TCP socket to establish critical co...
int get_udp_port()
Returns a new port number that will probably be free to use as a UDP port.
PN_uint8 get_uint8()
Extracts an unsigned 8-bit integer.
bool full() const
Returns true if the buffer is full; if this is true, push_back() will fail.
PN_uint32 get_uint32()
Extracts an unsigned 32-bit integer.
void idle()
Called each frame to do what needs to be done for the monitor's user-defined idle routines...
PN_uint16 get_uint16()
Extracts an unsigned 16-bit integer.
This is an abstract base class for a family of classes that listen for activity on a socket and respo...
This is an abstract class that presents the interface to any number of different front-ends for the s...
bool decode(const Datagram &datagram, PStatClientVersion *version)
Extracts the message from the indicated datagram.
void lost_connection()
This is called by the PStatServer when it detects that the connection has been lost.
void read_datagram(DatagramIterator &source, PStatClientVersion *version)
Extracts the FrameData definition from the datagram.
void pop_front()
Removes the first item from the buffer.
Contains the raw timing and level data for a single frame.
void remove_reader(Connection *connection, PStatReader *reader)
Removes the indicated reader.
static string get_host_name()
Returns the name of this particular machine on the network, if available, or the empty string if the ...
bool add_connection(Connection *connection)
Adds a new socket to the list of sockets the ConnectionReader will monitor.
The overall manager of the network connections.
A class to retrieve the individual data elements previously stored in a Datagram. ...
const Thing & front() const
Returns a reference to the first item in the queue.
Represents a single TCP or UDP socket for input or output.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
void release_udp_port(int port)
Indicates that the given UDP port is once again free for use.
bool close_connection(const PT(Connection) &connection)
Terminates a UDP or TCP socket previously opened.
void set_tcp_header_size(int tcp_header_size)
Sets the header size of TCP packets.
void close()
This will be called by the PStatClientData in response to its close() call.