1 // 2 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 // 7 // Official repository: https://github.com/vinniefalco/CppCon2018 8 // 9 10 #include "shared_state.hpp" 11 #include "websocket_session.hpp" 12 13 shared_state:: shared_state(std::string doc_root)14shared_state(std::string doc_root) 15 : doc_root_(std::move(doc_root)) 16 { 17 } 18 19 void 20 shared_state:: join(websocket_session * session)21join(websocket_session* session) 22 { 23 std::lock_guard<std::mutex> lock(mutex_); 24 sessions_.insert(session); 25 } 26 27 void 28 shared_state:: leave(websocket_session * session)29leave(websocket_session* session) 30 { 31 std::lock_guard<std::mutex> lock(mutex_); 32 sessions_.erase(session); 33 } 34 35 // Broadcast a message to all websocket client sessions 36 void 37 shared_state:: send(std::string message)38send(std::string message) 39 { 40 // Put the message in a shared pointer so we can re-use it for each client 41 auto const ss = boost::make_shared<std::string const>(std::move(message)); 42 43 // Make a local list of all the weak pointers representing 44 // the sessions, so we can do the actual sending without 45 // holding the mutex: 46 std::vector<boost::weak_ptr<websocket_session>> v; 47 { 48 std::lock_guard<std::mutex> lock(mutex_); 49 v.reserve(sessions_.size()); 50 for(auto p : sessions_) 51 v.emplace_back(p->weak_from_this()); 52 } 53 54 // For each session in our local list, try to acquire a strong 55 // pointer. If successful, then send the message on that session. 56 for(auto const& wp : v) 57 if(auto sp = wp.lock()) 58 sp->send(ss); 59 } 60