Apollo  6.0
Open source self driving car software
websocket_handler.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright 2017 The Apollo Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *****************************************************************************/
16 
21 #pragma once
22 
23 #include <memory>
24 #include <mutex>
25 #include <string>
26 #include <thread>
27 #include <unordered_map>
28 #include <vector>
29 
30 #include "CivetServer.h"
31 #include "nlohmann/json.hpp"
32 
37 namespace apollo {
38 namespace dreamview {
39 
46 class WebSocketHandler : public CivetWebSocketHandler {
47  // In case of receiving fragmented message,
48  // websocket opcode and accumulated data are stored.
49  thread_local static unsigned char current_opcode_;
50  thread_local static std::stringstream data_;
51 
52  public:
53  using Json = nlohmann::json;
54  using Connection = struct mg_connection;
55  using MessageHandler = std::function<void(const Json &, Connection *)>;
56  using ConnectionReadyHandler = std::function<void(Connection *)>;
57 
58  explicit WebSocketHandler(const std::string &name) : name_(name) {}
59 
68  bool handleConnection(CivetServer *server, const Connection *conn) override {
69  return true;
70  }
71 
79  void handleReadyState(CivetServer *server, Connection *conn) override;
80 
101  bool handleData(CivetServer *server, Connection *conn, int bits, char *data,
102  size_t data_len) override;
103 
104  bool handleJsonData(Connection *conn, const std::string &data);
105  bool handleBinaryData(Connection *conn, const std::string &data);
106 
113  void handleClose(CivetServer *server, const Connection *conn) override;
114 
119  bool BroadcastData(const std::string &data, bool skippable = false);
120 
129  bool SendData(Connection *conn, const std::string &data,
130  bool skippable = false, int op_code = MG_WEBSOCKET_OPCODE_TEXT);
131 
132  bool SendBinaryData(Connection *conn, const std::string &data,
133  bool skippable = false);
134 
140  void RegisterMessageHandler(std::string type, MessageHandler handler) {
141  message_handlers_[type] = handler;
142  }
143 
149  connection_ready_handlers_.emplace_back(handler);
150  }
151 
152  private:
153  const std::string name_;
154 
155  // Message handlers keyed by message type.
156  std::unordered_map<std::string, MessageHandler> message_handlers_;
157  // New connection ready handlers.
158  std::vector<ConnectionReadyHandler> connection_ready_handlers_;
159 
160  // The mutex guarding the connection set. We are not using read
161  // write lock, as the server is not expected to get many clients
162  // (connections).
163  // CAVEAT: Execution section while holding this global lock should be as
164  // brief as possible.
165  mutable std::mutex mutex_;
166 
167  // The pool of all maintained connections. Each connection has a lock to
168  // guard against simultaneous write.
169  std::unordered_map<Connection *, std::shared_ptr<std::mutex>> connections_;
170 };
171 
172 } // namespace dreamview
173 } // namespace apollo
nlohmann::json Json
Definition: websocket_handler.h:53
bool SendBinaryData(Connection *conn, const std::string &data, bool skippable=false)
WebSocketHandler(const std::string &name)
Definition: websocket_handler.h:58
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
void RegisterMessageHandler(std::string type, MessageHandler handler)
Add a new message handler for a message type.
Definition: websocket_handler.h:140
void RegisterConnectionReadyHandler(ConnectionReadyHandler handler)
Add a new handler for new connections.
Definition: websocket_handler.h:148
bool BroadcastData(const std::string &data, bool skippable=false)
Sends the provided data to all the connected clients.
bool SendData(Connection *conn, const std::string &data, bool skippable=false, int op_code=MG_WEBSOCKET_OPCODE_TEXT)
Sends the provided data to a specific connected client.
struct mg_connection Connection
Definition: websocket_handler.h:54
bool handleBinaryData(Connection *conn, const std::string &data)
void handleReadyState(CivetServer *server, Connection *conn) override
Callback method for when websocket handshake is successfully completed, and connection is ready for d...
void handleClose(CivetServer *server, const Connection *conn) override
Callback method for when the connection is closed.
bool handleJsonData(Connection *conn, const std::string &data)
std::function< void(Connection *)> ConnectionReadyHandler
Definition: websocket_handler.h:56
bool handleConnection(CivetServer *server, const Connection *conn) override
Callback method for when the client intends to establish a websocket connection, before websocket han...
Definition: websocket_handler.h:68
The WebSocketHandler, built on top of CivetWebSocketHandler, is a websocket handler that handles diff...
Definition: websocket_handler.h:46
std::function< void(const Json &, Connection *)> MessageHandler
Definition: websocket_handler.h:55
bool handleData(CivetServer *server, Connection *conn, int bits, char *data, size_t data_len) override
Callback method for when a data frame has been received from the client.