NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.0: 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 
33 NFD_LOG_INIT("WebSocketChannel");
34 
36  : m_localEndpoint(localEndpoint)
37  , m_pingInterval(10000)
38 {
39  setUri(FaceUri(m_localEndpoint, "ws"));
40 
41  // Be quiet
42  m_server.clear_access_channels(websocketpp::log::alevel::all);
43  m_server.clear_error_channels(websocketpp::log::elevel::all);
44 
45  // Setup WebSocket server
46  m_server.init_asio(&getGlobalIoService());
47  m_server.set_open_handler(bind(&WebSocketChannel::handleOpen, this, _1));
48  m_server.set_close_handler(bind(&WebSocketChannel::handleClose, this, _1));
49  m_server.set_message_handler(bind(&WebSocketChannel::handleMessage, this, _1, _2));
50 
51  // Detect disconnections using ping-pong messages
52  m_server.set_pong_handler(bind(&WebSocketChannel::handlePong, this, _1));
53  m_server.set_pong_timeout_handler(bind(&WebSocketChannel::handlePongTimeout, this, _1));
54 
55  // Always set SO_REUSEADDR flag
56  m_server.set_reuse_addr(true);
57 }
58 
59 void
60 WebSocketChannel::setPingInterval(time::milliseconds interval)
61 {
62  BOOST_ASSERT(!m_server.is_listening());
63 
64  m_pingInterval = interval;
65 }
66 
67 void
68 WebSocketChannel::setPongTimeout(time::milliseconds timeout)
69 {
70  BOOST_ASSERT(!m_server.is_listening());
71 
72  m_server.set_pong_timeout(static_cast<long>(timeout.count()));
73 }
74 
75 void
76 WebSocketChannel::handlePongTimeout(websocketpp::connection_hdl hdl)
77 {
78  auto it = m_channelFaces.find(hdl);
79  if (it != m_channelFaces.end()) {
80  static_cast<face::WebSocketTransport*>(it->second->getTransport())->handlePongTimeout();
81  }
82  else {
83  NFD_LOG_WARN("Pong timeout on unknown transport");
84  }
85 }
86 
87 void
88 WebSocketChannel::handlePong(websocketpp::connection_hdl hdl)
89 {
90  auto it = m_channelFaces.find(hdl);
91  if (it != m_channelFaces.end()) {
92  static_cast<face::WebSocketTransport*>(it->second->getTransport())->handlePong();
93  }
94  else {
95  NFD_LOG_WARN("Pong received on unknown transport");
96  }
97 }
98 
99 void
100 WebSocketChannel::handleMessage(websocketpp::connection_hdl hdl,
101  websocket::Server::message_ptr msg)
102 {
103  auto it = m_channelFaces.find(hdl);
104  if (it != m_channelFaces.end()) {
105  static_cast<face::WebSocketTransport*>(it->second->getTransport())->receiveMessage(msg->get_payload());
106  }
107  else {
108  NFD_LOG_WARN("Message received on unknown transport");
109  }
110 }
111 
112 void
113 WebSocketChannel::handleOpen(websocketpp::connection_hdl hdl)
114 {
115  auto linkService = make_unique<face::GenericLinkService>();
116  auto transport = make_unique<face::WebSocketTransport>(hdl, ref(m_server), m_pingInterval);
117  auto face = make_shared<Face>(std::move(linkService), std::move(transport));
118 
119  m_channelFaces[hdl] = face;
120  connectFaceClosedSignal(*face, [this, hdl] { m_channelFaces.erase(hdl); });
121 
122  m_onFaceCreatedCallback(face);
123 }
124 
125 void
126 WebSocketChannel::handleClose(websocketpp::connection_hdl hdl)
127 {
128  auto it = m_channelFaces.find(hdl);
129  if (it != m_channelFaces.end()) {
130  it->second->close();
131  }
132  else {
133  NFD_LOG_WARN("Close on unknown transport");
134  }
135 }
136 
137 void
139 {
140  if (m_server.is_listening()) {
141  NFD_LOG_WARN("[" << m_localEndpoint << "] Already listening");
142  return;
143  }
144 
145  m_onFaceCreatedCallback = onFaceCreated;
146  m_server.listen(m_localEndpoint);
147  m_server.start_accept();
148 }
149 
150 size_t
152 {
153  return m_channelFaces.size();
154 }
155 
156 } // namespace nfd
size_t size() const
Get number of faces in the channel.
represents the underlying protocol and address used by a Face
Definition: face-uri.hpp:44
void connectFaceClosedSignal(Face &face, const std::function< void()> &f)
invokes a callback when the face is closed
Definition: channel.cpp:41
detail::SimulatorIo & getGlobalIoService()
Definition: global-io.cpp:48
#define NFD_LOG_WARN(expression)
Definition: logger.hpp:58
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
void listen(const FaceCreatedCallback &onFaceCreated)
Enable listening on the local endpoint, accept connections, and create faces when remote host makes a...
void setUri(const FaceUri &uri)
Definition: channel.cpp:35
#define NFD_LOG_INIT(name)
Definition: logger.hpp:34
function< void(const shared_ptr< Face > &newFace)> FaceCreatedCallback
Prototype for the callback that is invoked when the face is created (as a response to incoming connec...
Definition: channel.hpp:38
boost::asio::ip::tcp::endpoint Endpoint