NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.3: NDN, CCN, CCNx, content centric networks
API Documentation
websocket-channel.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
26 #include "websocket-channel.hpp"
27 #include "generic-link-service.hpp"
28 #include "websocket-transport.hpp"
29 #include "core/global-io.hpp"
30 
31 namespace nfd {
32 namespace face {
33 
34 NFD_LOG_INIT("WebSocketChannel");
35 
37  : m_localEndpoint(localEndpoint)
38  , m_pingInterval(time::seconds(10))
39 {
40  setUri(FaceUri(m_localEndpoint, "ws"));
41  NFD_LOG_CHAN_INFO("Creating channel");
42 
43  // Be quiet
46 
47  // Setup WebSocket server
48  m_server.init_asio(&getGlobalIoService());
49  m_server.set_open_handler(bind(&WebSocketChannel::handleOpen, this, _1));
50  m_server.set_close_handler(bind(&WebSocketChannel::handleClose, this, _1));
51  m_server.set_message_handler(bind(&WebSocketChannel::handleMessage, this, _1, _2));
52 
53  // Detect disconnections using ping-pong messages
54  m_server.set_pong_handler(bind(&WebSocketChannel::handlePong, this, _1));
55  m_server.set_pong_timeout_handler(bind(&WebSocketChannel::handlePongTimeout, this, _1));
56 
57  // Always set SO_REUSEADDR flag
58  m_server.set_reuse_addr(true);
59 }
60 
61 void
62 WebSocketChannel::setPingInterval(time::milliseconds interval)
63 {
64  BOOST_ASSERT(!m_server.is_listening());
65 
66  m_pingInterval = interval;
67 }
68 
69 void
70 WebSocketChannel::setPongTimeout(time::milliseconds timeout)
71 {
72  BOOST_ASSERT(!m_server.is_listening());
73 
74  m_server.set_pong_timeout(static_cast<long>(timeout.count()));
75 }
76 
77 void
78 WebSocketChannel::handlePongTimeout(websocketpp::connection_hdl hdl)
79 {
80  auto it = m_channelFaces.find(hdl);
81  if (it != m_channelFaces.end()) {
82  static_cast<WebSocketTransport*>(it->second->getTransport())->handlePongTimeout();
83  }
84  else {
85  NFD_LOG_CHAN_WARN("Pong timeout on unknown transport");
86  }
87 }
88 
89 void
90 WebSocketChannel::handlePong(websocketpp::connection_hdl hdl)
91 {
92  auto it = m_channelFaces.find(hdl);
93  if (it != m_channelFaces.end()) {
94  static_cast<WebSocketTransport*>(it->second->getTransport())->handlePong();
95  }
96  else {
97  NFD_LOG_CHAN_WARN("Pong received on unknown transport");
98  }
99 }
100 
101 void
102 WebSocketChannel::handleMessage(websocketpp::connection_hdl hdl,
104 {
105  auto it = m_channelFaces.find(hdl);
106  if (it != m_channelFaces.end()) {
107  static_cast<WebSocketTransport*>(it->second->getTransport())->receiveMessage(msg->get_payload());
108  }
109  else {
110  NFD_LOG_CHAN_WARN("Message received on unknown transport");
111  }
112 }
113 
114 void
115 WebSocketChannel::handleOpen(websocketpp::connection_hdl hdl)
116 {
117  NFD_LOG_CHAN_TRACE("Incoming connection from " << m_server.get_con_from_hdl(hdl)->get_remote_endpoint());
118 
119  auto linkService = make_unique<GenericLinkService>();
120  auto transport = make_unique<WebSocketTransport>(hdl, ref(m_server), m_pingInterval);
121  auto face = make_shared<Face>(std::move(linkService), std::move(transport));
122 
123  BOOST_ASSERT(m_channelFaces.count(hdl) == 0);
124  m_channelFaces[hdl] = face;
125  connectFaceClosedSignal(*face, [this, hdl] { m_channelFaces.erase(hdl); });
126 
127  m_onFaceCreatedCallback(face);
128 }
129 
130 void
131 WebSocketChannel::handleClose(websocketpp::connection_hdl hdl)
132 {
133  auto it = m_channelFaces.find(hdl);
134  if (it != m_channelFaces.end()) {
135  it->second->close();
136  }
137  else {
138  NFD_LOG_CHAN_WARN("Close on unknown transport");
139  }
140 }
141 
142 void
144 {
145  if (isListening()) {
146  NFD_LOG_CHAN_WARN("Already listening");
147  return;
148  }
149 
150  m_onFaceCreatedCallback = onFaceCreated;
151 
152  m_server.listen(m_localEndpoint);
153  m_server.start_accept();
154  NFD_LOG_CHAN_DEBUG("Started listening");
155 }
156 
157 } // namespace face
158 } // namespace nfd
static level const all
Special aggregate value representing "all levels".
Definition: levels.hpp:152
void listen(const FaceCreatedCallback &onFaceCreated)
Enable listening on the local endpoint, accept connections, and create faces when remote host makes a...
void set_pong_timeout_handler(pong_timeout_handler h)
Definition: endpoint.hpp:302
void setUri(const FaceUri &uri)
Definition: channel.cpp:34
void set_open_handler(open_handler h)
Definition: endpoint.hpp:277
void set_reuse_addr(bool value)
Sets whether to use the SO_REUSEADDR flag when opening listening sockets.
Definition: endpoint.hpp:342
boost::posix_time::time_duration milliseconds(long duration)
Definition: asio.hpp:117
connection_type::message_ptr message_ptr
Type of message pointers that this endpoint uses.
Definition: endpoint.hpp:70
lib::weak_ptr< void > connection_hdl
A handle to uniquely identify a connection.
detail::SimulatorIo & getGlobalIoService()
Definition: global-io.cpp:48
connection_ptr get_con_from_hdl(connection_hdl hdl, lib::error_code &ec)
Retrieves a connection_ptr from a connection_hdl (exception free)
Definition: endpoint.hpp:643
void connectFaceClosedSignal(Face &face, const std::function< void()> &f)
invokes a callback when the face is closed
Definition: channel.cpp:40
void set_close_handler(close_handler h)
Definition: endpoint.hpp:282
void init_asio(io_service_ptr ptr, lib::error_code &ec)
initialize asio transport with external io_service (exception free)
Definition: endpoint.hpp:181
#define NFD_LOG_CHAN_DEBUG(msg)
Log a message at DEBUG level.
Definition: channel-log.hpp:49
WebSocketChannel(const websocket::Endpoint &localEndpoint)
Create WebSocket channel for the local endpoint.
Copyright (c) 2011-2015 Regents of the University of California.
Definition: ndn-common.hpp:40
bool is_listening() const
Check if the endpoint is listening.
Definition: endpoint.hpp:608
#define NFD_LOG_CHAN_INFO(msg)
Log a message at INFO level.
Definition: channel-log.hpp:52
#define NFD_LOG_CHAN_TRACE(msg)
Log a message at TRACE level.
Definition: channel-log.hpp:46
#define NFD_LOG_CHAN_WARN(msg)
Log a message at WARN level.
Definition: channel-log.hpp:55
void start_accept(lib::error_code &ec)
Starts the server&#39;s async connection acceptance loop (exception free)
void set_pong_handler(pong_handler h)
Definition: endpoint.hpp:297
void clear_error_channels(log::level channels)
Clear Error logging channels.
Definition: endpoint.hpp:253
represents the underlying protocol and address used by a Face
Definition: face-uri.hpp:43
bool isListening() const override
Returns whether the channel is listening.
void clear_access_channels(log::level channels)
Clear Access logging channels.
Definition: endpoint.hpp:231
A Transport that communicates on a WebSocket connection.
void set_pong_timeout(long dur)
Set pong timeout.
Definition: endpoint.hpp:399
boost::asio::ip::tcp::endpoint Endpoint
void listen(lib::asio::ip::tcp::endpoint const &ep, lib::error_code &ec)
Set up endpoint for listening manually (exception free)
Definition: endpoint.hpp:391
#define NFD_LOG_INIT(name)
Definition: logger.hpp:34
void set_message_handler(message_handler h)
Definition: endpoint.hpp:322
static level const all
Special aggregate value representing "all levels".
Definition: levels.hpp:80
function< void(const shared_ptr< Face > &newFace)> FaceCreatedCallback
Prototype for the callback that is invoked when a face is created (in response to an incoming connect...
Definition: channel.hpp:35