5 #include <stdint.h> |
5 #include <stdint.h> |
6 |
6 |
7 // forward-declare |
7 // forward-declare |
8 class NetworkSession; |
8 class NetworkSession; |
9 |
9 |
10 /* |
10 /** |
11 * Used to separate packets, ID zero is reserved for NetworkSession use |
11 * A NetworkSession puts each packet onto a specific channel, which can the be used to run multiple different modules |
|
12 * on top of a single session. |
|
13 * |
|
14 * NetworkChannelID zero is reserved for internal NetworkSession use |
12 */ |
15 */ |
13 typedef uint16_t NetworkChannelID; |
16 typedef uint16_t NetworkChannelID; |
14 |
17 |
15 /* |
18 /** |
16 * Size of a packet header |
19 * Size of a NetworkSession's packet header: |
|
20 * uint16 channel_id |
17 */ |
21 */ |
18 const size_t NETWORK_SESSION_HEADER_SIZE = sizeof(uint16_t); |
22 const size_t NETWORK_SESSION_HEADER_SIZE = sizeof(uint16_t); |
19 |
23 |
20 #include "TCP.hh" |
24 #include "TCP.hh" |
21 #include "UDP.hh" |
25 #include "UDP.hh" |
22 #include "Node.hh" |
26 #include "Node.hh" |
23 |
27 |
|
28 /** |
|
29 * A NetworkSession provides TCP/UDP Server and Client functionality, representing remote NetworkSessions with |
|
30 * NetworkNodes. A NetworkSession can then communicate with its NetworkNodes using TCP or UDP NetworkPackets. |
|
31 */ |
24 class NetworkSession { |
32 class NetworkSession { |
25 friend class NetworkNode; |
33 friend class NetworkNode; |
26 |
34 |
27 private: |
35 private: |
|
36 /** |
|
37 * The application's magic ID |
|
38 */ |
28 uint64_t magic; |
39 uint64_t magic; |
|
40 |
|
41 /** |
|
42 * Our TCP server, if we're in listen() mode |
|
43 */ |
29 NetworkTCPServer *tcp_srv; |
44 NetworkTCPServer *tcp_srv; |
30 NetworkUDP *udp_srv, *udp_client; |
|
31 |
45 |
|
46 /** |
|
47 * Our UDP server, if we're in listen() mode |
|
48 */ |
|
49 NetworkUDP *udp_srv; |
|
50 |
|
51 /** |
|
52 * Our UDP client, if we're in connect() mode |
|
53 */ |
|
54 NetworkUDP *udp_client; |
|
55 |
32 CL_SlotContainer slots; |
56 CL_SlotContainer slots; |
|
57 |
|
58 /** |
|
59 * A map of NetworkAddress -> NetworkNode, manipulated when TCP connections are established/broken down, |
|
60 * and used to map UDP packets to their NetworkNode |
|
61 */ |
|
62 std::map<NetworkAddress, NetworkNode*> nodes; |
33 |
63 |
34 std::map<NetworkAddress, NetworkNode*> nodes; |
64 /** |
|
65 * A map of NetworkChannelID -> signal, used to signal our users when we receieve packets |
|
66 */ |
35 std::map<NetworkChannelID, CL_Signal_v2<NetworkPacketInput&, NetworkNode *> > _map_sig_chan_message; |
67 std::map<NetworkChannelID, CL_Signal_v2<NetworkPacketInput&, NetworkNode *> > _map_sig_chan_message; |
36 |
68 |
37 public: |
69 public: |
|
70 /** |
|
71 * Construct an idle NetworkSession using the given application magic, which should be unique to tell different |
|
72 * applications apart from each other. |
|
73 * |
|
74 * @param magic unique application magic |
|
75 */ |
38 NetworkSession (uint64_t magic); |
76 NetworkSession (uint64_t magic); |
|
77 |
|
78 /** |
|
79 * Have the NetworkSession enter server mode, listening on the given address using both TCP and UDP |
|
80 * |
|
81 * @param addr local address to listen on |
|
82 */ |
|
83 void listen (const NetworkAddress &addr); |
39 |
84 |
40 void listen (const NetworkAddress &addr); |
85 /** |
|
86 * Have the NetworkSession enter client mode, establishing a TCP connection to the server, and then allocating |
|
87 * an UDP socket on the same local address as the TCP connection. |
|
88 * |
|
89 * @param addr remote address to connect to |
|
90 */ |
41 NetworkNode* connect (const NetworkAddress &addr); |
91 NetworkNode* connect (const NetworkAddress &addr); |
42 |
92 |
43 protected: |
93 protected: |
|
94 /** |
|
95 * Used to build a new NetworkNode by connect/on_tcp_client. Can be used to override what kind of NetworkNodes |
|
96 * get created. Type tells what kind of node this is. |
|
97 * |
|
98 * @param tcp the TCP transport for this node |
|
99 * @param udp the UDP socket to use for this node |
|
100 * @param addr the remote address |
|
101 * @param type the type of node |
|
102 * @see NetworkNodeType |
|
103 */ |
44 virtual NetworkNode *build_node (NetworkTCPTransport *tcp, NetworkUDP *udp, const NetworkAddress &addr, enum NetworkNodeType type); |
104 virtual NetworkNode *build_node (NetworkTCPTransport *tcp, NetworkUDP *udp, const NetworkAddress &addr, enum NetworkNodeType type); |
45 |
105 |
|
106 /** |
|
107 * A NetworkNode's TCP connection has failed. Removes the node from our nodes-map (using node->getRemoteAddress) |
|
108 * |
|
109 * @param node the node that has disconnected |
|
110 */ |
46 void handle_disconnect (NetworkNode *node); |
111 void handle_disconnect (NetworkNode *node); |
|
112 |
|
113 /** |
|
114 * We have received a NetworkPacket from the given node (either TCP or UDP, we don't know) |
|
115 * |
|
116 * @param pkt the NetworkPacket that we received |
|
117 * @param node the node that sent it |
|
118 */ |
47 void handle_message (NetworkPacketInput &pkt, NetworkNode *node); |
119 void handle_message (NetworkPacketInput &pkt, NetworkNode *node); |
48 |
120 |
49 private: |
121 private: |
|
122 /** |
|
123 * Our tcp_srv has accept()'d a new client. |
|
124 * |
|
125 * Create a NetworkNode using build_node and udp_srv, add it to our node-map, and trigger sig_node_connected |
|
126 */ |
50 void on_tcp_client (NetworkTCPTransport *client); |
127 void on_tcp_client (NetworkTCPTransport *client); |
|
128 |
|
129 /** |
|
130 * Our udp_srv has recv()'d a NetworkPacket. |
|
131 * |
|
132 * Map it to a NetworkNode using our node-map and call handle_message |
|
133 */ |
51 void on_udp_packet (NetworkPacketInput &pkt, const NetworkAddress &addr); |
134 void on_udp_packet (NetworkPacketInput &pkt, const NetworkAddress &addr); |
52 |
135 |
|
136 /** |
|
137 * New-client signal |
|
138 */ |
53 CL_Signal_v1<NetworkNode*> _sig_node_connected; |
139 CL_Signal_v1<NetworkNode*> _sig_node_connected; |
54 |
140 |
55 public: |
141 public: |
|
142 /** |
|
143 * Send the given NetworkPacket to all our nodes using the given NetworkChannelID, using TCP if reliable, UDP otherwise. |
|
144 * |
|
145 * @param channel_id the NetworkChannelID to use |
|
146 * @param pkt the NetworkPacket to send |
|
147 * @param reliable Whether to use TCP or UDP |
|
148 */ |
56 void send_all (NetworkChannelID channel_id, const NetworkPacketBuffer &pkt, bool reliable = true); |
149 void send_all (NetworkChannelID channel_id, const NetworkPacketBuffer &pkt, bool reliable = true); |
|
150 |
|
151 /** |
|
152 * Like send_all, but do not send the packet to the specified node. If node is NULL, this behaves like |
|
153 * send_all. |
|
154 * |
|
155 * @see send_all |
|
156 */ |
57 void send_all_except (NetworkChannelID channel_id, const NetworkPacketBuffer &pkt, const NetworkNode *node, bool reliable = true); |
157 void send_all_except (NetworkChannelID channel_id, const NetworkPacketBuffer &pkt, const NetworkNode *node, bool reliable = true); |
58 |
158 |
|
159 /** |
|
160 * A new node has connected to us |
|
161 */ |
|
162 CL_Signal_v1<NetworkNode*>& sig_node_connected (void) { return _sig_node_connected; } |
59 |
163 |
60 CL_Signal_v1<NetworkNode*>& sig_node_connected (void) { return _sig_node_connected; } |
164 /** |
|
165 * We have received a NetworkPacket from a NetworkNode on the given NetworkChannelID |
|
166 */ |
61 CL_Signal_v2<NetworkPacketInput&, NetworkNode *>& sig_chan_message (NetworkChannelID cid) { return _map_sig_chan_message[cid]; } |
167 CL_Signal_v2<NetworkPacketInput&, NetworkNode *>& sig_chan_message (NetworkChannelID cid) { return _map_sig_chan_message[cid]; } |
62 }; |
168 }; |
63 |
169 |
64 #endif /* NETWORK_SESSION_HH */ |
170 #endif /* NETWORK_SESSION_HH */ |