OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef GOOGLE_APIS_GCM_ENGINE_CONNECTION_HANDLER_H_ | 5 #ifndef GOOGLE_APIS_GCM_ENGINE_CONNECTION_HANDLER_IMPL_H_ |
6 #define GOOGLE_APIS_GCM_ENGINE_CONNECTION_HANDLER_H_ | 6 #define GOOGLE_APIS_GCM_ENGINE_CONNECTION_HANDLER_IMPL_H_ |
7 | 7 |
8 #include "base/memory/weak_ptr.h" | 8 #include "base/memory/weak_ptr.h" |
| 9 #include "base/time/time.h" |
9 #include "base/timer/timer.h" | 10 #include "base/timer/timer.h" |
10 #include "google_apis/gcm/base/gcm_export.h" | 11 #include "google_apis/gcm/engine/connection_handler.h" |
11 #include "google_apis/gcm/protocol/mcs.pb.h" | |
12 | 12 |
13 namespace net{ | 13 namespace mcs_proto { |
14 class StreamSocket; | 14 class LoginRequest; |
15 } | 15 } // namespace mcs_proto |
16 | 16 |
17 namespace gcm { | 17 namespace gcm { |
18 | 18 |
19 class SocketInputStream; | 19 class GCM_EXPORT ConnectionHandlerImpl : public ConnectionHandler { |
20 class SocketOutputStream; | |
21 | |
22 // Handles performing the protocol handshake and sending/receiving protobuf | |
23 // messages. Note that no retrying or queueing is enforced at this layer. | |
24 // Once a connection error is encountered, the ConnectionHandler will disconnect | |
25 // the socket and must be reinitialized with a new StreamSocket before | |
26 // messages can be sent/received again. | |
27 class GCM_EXPORT ConnectionHandler { | |
28 public: | 20 public: |
29 typedef base::Callback<void(scoped_ptr<google::protobuf::MessageLite>)> | |
30 ProtoReceivedCallback; | |
31 typedef base::Closure ProtoSentCallback; | |
32 typedef base::Callback<void(int)> ConnectionChangedCallback; | |
33 | |
34 explicit ConnectionHandler(base::TimeDelta read_timeout); | |
35 ~ConnectionHandler(); | |
36 | |
37 // Starts a new MCS connection handshake (using |login_request|) and, upon | |
38 // success, begins listening for incoming/outgoing messages. A successful | |
39 // handshake is when a mcs_proto::LoginResponse is received, and is signaled | |
40 // via the |read_callback|. | |
41 // Outputs: | |
42 // |read_callback| will be invoked with the contents of any received protobuf | 21 // |read_callback| will be invoked with the contents of any received protobuf |
43 // message. | 22 // message. |
44 // |write_callback| will be invoked anytime a message has been successfully | 23 // |write_callback| will be invoked anytime a message has been successfully |
45 // sent. Note: this just means the data was sent to the wire, not that the | 24 // sent. Note: this just means the data was sent to the wire, not that the |
46 // other end received it. | 25 // other end received it. |
47 // |connection_callback| will be invoked with any fatal read/write errors | 26 // |connection_callback| will be invoked with any fatal read/write errors |
48 // encountered. | 27 // encountered. |
49 // | 28 ConnectionHandlerImpl( |
50 // Note: It is correct and expected to call Init more than once, as connection | 29 base::TimeDelta read_timeout, |
51 // issues are encountered and new connections must be made. | 30 const ProtoReceivedCallback& read_callback, |
52 void Init(scoped_ptr<net::StreamSocket> socket, | 31 const ProtoSentCallback& write_callback, |
53 const google::protobuf::MessageLite& login_request, | 32 const ConnectionChangedCallback& connection_callback); |
54 const ProtoReceivedCallback& read_callback, | 33 virtual ~ConnectionHandlerImpl(); |
55 const ProtoSentCallback& write_callback, | |
56 const ConnectionChangedCallback& connection_callback); | |
57 | 34 |
58 // Checks that a handshake has been completed and a message is not already | 35 // ConnectionHandler implementation. |
59 // in flight. | 36 virtual void Init(const mcs_proto::LoginRequest& login_request, |
60 bool CanSendMessage() const; | 37 scoped_ptr<net::StreamSocket> socket) OVERRIDE; |
61 | 38 virtual bool CanSendMessage() const OVERRIDE; |
62 // Send an MCS protobuf message. CanSendMessage() must be true. | 39 virtual void SendMessage(const google::protobuf::MessageLite& message) |
63 void SendMessage(const google::protobuf::MessageLite& message); | 40 OVERRIDE; |
64 | 41 |
65 private: | 42 private: |
66 // State machine for handling incoming data. See WaitForData(..) for usage. | 43 // State machine for handling incoming data. See WaitForData(..) for usage. |
67 enum ProcessingState { | 44 enum ProcessingState { |
68 // Processing the version, tag, and size packets (assuming minimum length | 45 // Processing the version, tag, and size packets (assuming minimum length |
69 // size packet). Only used during the login handshake. | 46 // size packet). Only used during the login handshake. |
70 MCS_VERSION_TAG_AND_SIZE = 0, | 47 MCS_VERSION_TAG_AND_SIZE = 0, |
71 // Processing the tag and size packets (assuming minimum length size | 48 // Processing the tag and size packets (assuming minimum length size |
72 // packet). Used for normal messages. | 49 // packet). Used for normal messages. |
73 MCS_TAG_AND_SIZE, | 50 MCS_TAG_AND_SIZE, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 // Closes the current connection. | 86 // Closes the current connection. |
110 void CloseConnection(); | 87 void CloseConnection(); |
111 | 88 |
112 // Timeout policy: the timeout is only enforced while waiting on the | 89 // Timeout policy: the timeout is only enforced while waiting on the |
113 // handshake (version and/or LoginResponse) or once at least a tag packet has | 90 // handshake (version and/or LoginResponse) or once at least a tag packet has |
114 // been received. It is reset every time new data is received, and is | 91 // been received. It is reset every time new data is received, and is |
115 // only stopped when a full message is processed. | 92 // only stopped when a full message is processed. |
116 // TODO(zea): consider enforcing a separate timeout when waiting for | 93 // TODO(zea): consider enforcing a separate timeout when waiting for |
117 // a message to send. | 94 // a message to send. |
118 const base::TimeDelta read_timeout_; | 95 const base::TimeDelta read_timeout_; |
119 base::OneShotTimer<ConnectionHandler> read_timeout_timer_; | 96 base::OneShotTimer<ConnectionHandlerImpl> read_timeout_timer_; |
120 | 97 |
121 // This connection's socket and the input/output streams attached to it. | 98 // This connection's socket and the input/output streams attached to it. |
122 scoped_ptr<net::StreamSocket> socket_; | 99 scoped_ptr<net::StreamSocket> socket_; |
123 scoped_ptr<SocketInputStream> input_stream_; | 100 scoped_ptr<SocketInputStream> input_stream_; |
124 scoped_ptr<SocketOutputStream> output_stream_; | 101 scoped_ptr<SocketOutputStream> output_stream_; |
125 | 102 |
126 // Whether the MCS login handshake has successfully completed. See Init(..) | 103 // Whether the MCS login handshake has successfully completed. See Init(..) |
127 // description for more info on what the handshake involves. | 104 // description for more info on what the handshake involves. |
128 bool handshake_complete_; | 105 bool handshake_complete_; |
129 | 106 |
130 // State for the message currently being processed, if there is one. | 107 // State for the message currently being processed, if there is one. |
131 uint8 message_tag_; | 108 uint8 message_tag_; |
132 uint32 message_size_; | 109 uint32 message_size_; |
133 | 110 |
134 ProtoReceivedCallback read_callback_; | 111 ProtoReceivedCallback read_callback_; |
135 ProtoSentCallback write_callback_; | 112 ProtoSentCallback write_callback_; |
136 ConnectionChangedCallback connection_callback_; | 113 ConnectionChangedCallback connection_callback_; |
137 | 114 |
138 base::WeakPtrFactory<ConnectionHandler> weak_ptr_factory_; | 115 base::WeakPtrFactory<ConnectionHandlerImpl> weak_ptr_factory_; |
139 | 116 |
140 DISALLOW_COPY_AND_ASSIGN(ConnectionHandler); | 117 DISALLOW_COPY_AND_ASSIGN(ConnectionHandlerImpl); |
141 }; | 118 }; |
142 | 119 |
143 } // namespace gcm | 120 } // namespace gcm |
144 | 121 |
145 #endif // GOOGLE_APIS_GCM_ENGINE_CONNECTION_HANDLER_H_ | 122 #endif // GOOGLE_APIS_GCM_ENGINE_CONNECTION_HANDLER_IMPL_H_ |
OLD | NEW |